#c #inheritance #interface #abstract-class #unique-ptr
#c #наследование #интерфейс #абстрактный класс #уникальный-ptr
Вопрос:
Предположим, мы хотим реализовать шаблон стратегии. У нас есть интерфейс Base
и два производных класса — A
и B
. Экземпляры Doer
класса могут выбирать между A
‘s и B
‘s методами do()
. И вопрос в том, как завершить код, чтобы сделать так, как это должно быть.
class Base {
virtual void do() const = 0;
};
class A: public Base {
void do() const override {};
};
class B: public Base {
void do() const override {};
}
class Doer {
public:
Doer(std::unique_ptr<Base> b_ptr) : ptr(b_ptr) {}
void do() const { ptr->do(); }
private:
std::unique_ptr<Base> ptr;
}
int main() {
Doer doer(std::unique_ptr<Base>());
doer.do();
return 0;
}
Ответ №1:
Doer doer(std::make_unique<A>()); // or std::make_unique<B>()
Вышесказанное в значительной степени это. std::unique_ptr
очень сложно реализовать то же принуждение, что и исходный указатель, который он содержит.
Ответ №2:
В вашем коде есть три основные проблемы.
1) do
является ключевым словом языка. Вы не можете использовать его в качестве идентификатора (например, имени функции)
2) вы принимаете b_ptr
по значению, поэтому вам нужно перейти от него:
Doer(std::unique_ptr<Base> b_ptr) : ptr(std::move(b_ptr)) {}
3) вы передаете пустой unique_ptr
в Doer
конструктор, что эквивалентно передаче nullptr
. Вы также пытаетесь создать экземпляр базового класса. Это невозможно, потому что Base
это чисто виртуальный класс. Использовать make_unique
с производным типом:
Doer doer(std::make_unique<A>());