Начал изучать книгу Эрика и Элизабет Фримен Паттерны проектирования. Пытаюсь написать на C++ архитектуру из первой главы.
Как в конструкторе наследника Duck (RedheadDuck) присвоить указателю FlyBehaviour FlyWithWings? В FlyWithWings одна статическая функция, и не хотелось бы создавать где-то в main()-е экземпляр, а потом передавать его в конструктор, можно ли как-то этого избежать?
Код:
class FlyBehaviour {
public:
static virtual void fly() = 0;
};
class FlyWithWings : public FlyBehaviour {
public:
static void fly() {
cout << "I'm flying with wings!" << endl;
}
};
class Duck {
private:
FlyBehaviour *flyBehaviour;
public:
virtual void display() = 0;
void fly() {flyBehaviour->fly();}
};
class RedheadDuck : public Duck {
RedheadDuck() {
// Как присвоить flyBehaviour указатель на FlyWithWings?
}
void display() {
cout << "I'm redhead duck." << endl;
}
};
Всем спасибо, сделал так:
class FlyBehaviour {
public:
virtual void fly() = 0;
};
class FlyWithWings : public FlyBehaviour {
public:
void fly() {
cout << "I'm flying with wings!" << endl;
}
};
class Duck {
protected:
FlyBehaviour *flyBehaviour;
public:
Duck() {flyBehaviour = nullptr;}
virtual void display() = 0;
void fly() {flyBehaviour->fly();}
~Duck() {delete flyBehaviour;}
};
class RedheadDuck : public Duck {
public:
RedheadDuck() {
Duck::flyBehaviour = new FlyWithWings;
}
void display() {
cout << "I'm redhead duck." << endl;
}
};
Если я вас правильно понял, то так:
class RedheadDuck : public Duck {
RedheadDuck(FlyBehaviour *in) : Duck{in} {
}
void display() {
cout << "I'm redhead duck." << endl;
}
};
Как видите, сдесь не хватает соответствующего конструктора для Duck
class Duck {
private:
FlyBehaviour *flyBehaviour;
public:
Duck(FlyBehaviour *in) : flyBehaviour{in}{};
virtual void display() = 0;
void fly() {flyBehaviour->fly();}
};
Если же вы не хотите каждый раз явно указывать при инициализации чем его нужно инициализировать, то установите аргумент по умолчанию:
RedheadDuck(FlyBehaviour *in = new FlyWithWings) : Duck{in}
Так, если вы не передадите при инициализации аргументы, будет использован аргумент по умолчанию, но если вам нужен другой аргумент, то придется использовать его при явной инициализации.
Главное, раз уж работаете с указателями, предусмотрите освобождение памяти в деструкторе, либо используйте интеллектуальные указатели
Чтобы присвоить указатель на экземпляр FlyWithWings
этот экземпляр сначала надо создать, а это сделать невозможно, так как это абстрактный класс, так как он не реализует метод fly
. Встроенная система полиморфизма не допускает статических виртуальных методов. Так что static virtual void fly() = 0;
является ошибкой синтаксиса. Делайте метод не статическим, реализуйте его в FlyWithWings
, создавайте экземпляр FlyWithWings
и присваивайте указателю адрес этого экземпляра. Если же никакого состояния хранить не требуется, то можно вместо указателя на класс использовать указатель на метод.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Установил давно java10 и Intelij Idea, все прекрасно работалоВ один день при открытии Intelij Idea появилась ошибка
Есть вес кошки, есть максимальный и минимальный возможный вес, при выходе за пределы допустимого веса кошка умираетКак заморозить переменную...
Есть программа, которая позволяет пользователю войти и добавить продуктыПри регистрации отправляется линк для активации профиля это в email - е выглядит...