Błąd kompilacji kodu z funkcjami wirtualnymi

0

Witam, głowię się od jakiegoś czasu nad kodem czemu on nie działa, umiem w programować w Javie ale C++ naraz mnie przerasta z góry dzięki

#include <iostream>
#include <string>
#include <sstream>
#include <exception>
#include <regex>

class InvalidAddressException : public std::exception {
private:
    std::string message;
public:
    InvalidAddressException(std::string message) {
        this->message = message;
    };

    const char *what() {
        return (this->message).c_str();
    }
};

template<class T>
class Address {
private:
    T value;
protected:
    Address(T value) {
        this->value = value;
    }

    virtual bool isValid(T text) {
        std::cout << "This method should be override" << std::endl;
        return false;
    };

    virtual T returnValueWhenValidOrElseThrowException(T text) {
        std::cout << "This method should be override" << std::endl;
        return T();
    }

public:
    std::string toString() {
        std::ostringstream valueStream;
        valueStream << this->value;
        return valueStream.str();
    };
};

class BinaryAddress : public Address<std::string> {
private:
    bool isValid(std::string text) override {
        std::cout << "hello" << std::endl;
//        std::string binaryAddressRegex = "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
//        return std::regex_match(text, std::regex(binaryAddressRegex));
        return true;
    }

    std::string returnValueWhenValidOrElseThrowException(std::string text) override {
        std::cout << "hello" << std::endl;
        if (this->isValid(text))
            return text;
        else
            throw InvalidAddressException("Invalid binary address exception");
    }

public:
    explicit BinaryAddress(const std::string &address) : Address(returnValueWhenValidOrElseThrowException(address)) {}
};

class DecimalAddress : public Address<std::string> {
public:
    explicit DecimalAddress(const std::string &address) : Address(address) {}

protected:
    std::string returnValueWhenValidOrElseThrowException(std::string text) override {
        return Address::returnValueWhenValidOrElseThrowException(text);
    }
};

class NumberOfOnesAddress : public Address<int> {
public:
    explicit NumberOfOnesAddress(const int &address) : Address(address) {}

protected:
    int returnValueWhenValidOrElseThrowException(int text) override {
        return Address::returnValueWhenValidOrElseThrowException(text);
    }
};

int main() {
    BinaryAddress binaryAddress = BinaryAddress("11000000.10101000.00000000.00000001");
//    DecimalAddress decimalAddress = DecimalAddress("192.168.0.100");
//    NumberOfOnesAddress numberOfOnesAddress = NumberOfOnesAddress(11);
    std::cout << binaryAddress.toString() << std::endl;
//    std::cout << decimalAddress.toString() << std::endl;
//    std::cout << numberOfOnesAddress.toString() << std::endl;
    return 0;
}
5

Korzystasz z funkcji wirtualnych klasy przed jej inicjalizacją, to UB.

Ogółem strasznie przekombinowany ten kod, ciężko się w nim połapać, a przecież nic skomplikowanego nie robi.

  1. Nie używaj virtual jeśli nie musisz - w tym przykładzie nie musisz, w rzeczywistym zapewne też nie.
  2. Jeśli chcesz mieć tylko interfejs, bez implementacji, dla funkcji wirtualnej - użyj =0
  3. InvalidAddressException możesz dziedziczyć po std::runtime_error, wtedy odpada właściwie cała implementacja.
1
꧁Oziaka꧂ napisał(a):

Witam, głowię się od jakiegoś czasu nad kodem czemu on nie działa, umiem w programować w Javie ale C++ naraz mnie przerasta z góry dzięki

Wprawdzie syntaktycznie klasy abstrakcyjne nieco się różnią w obu językach, ale sens już o wiele bliższy.
Nie wiem, czy w Javie byś idealnie zachował wzorzec użycia klasy abstrakcyjnej. Moze tak, może nie.
W żadnym języku nie robi się tego przez a) zaimplementowanie b) pisanie czegoś w rodzaju "nie używaj"

1 użytkowników online, w tym zalogowanych: 0, gości: 1