2016-10-23 5 views
2

Предположим, мы хотим реализовать стратегический шаблон. У нас есть интерфейс Base и два производных класса - A и B. Экземпляры класса Doer могут выбирать между A и B методами do(). И вопрос в том, как заполнить код, чтобы сделать, как это должно быть.Как работать с функциями std :: make_unique и интерфейсами?

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; 
} 

ответ

3

Существуют три основные проблемы с вашим кодом.

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>()); 
4
Doer doer(std::make_unique<A>()); // or std::make_unique<B>() 

выше довольно много его. std::unique_ptr работает очень сложно для реализации того же принуждения, что и исходный указатель.