Как передать производный объект в класс в C ++? - PullRequest
0 голосов
/ 30 мая 2018

Я думаю, что что-то не так с наследованием C ++.

Допустим, у меня есть это классическое наследование:

    class A{
    public: 
        virtual void method1() =0;
        virtual ~A() = default;
    }

    class B : public A{
    public :
        void method1(){doSomething();}
    }

    class C : public A{
    public :
        void method1(){doSomethingElse();}
    }

Как заставить другой класс Q иметь объект типа B или C, не зная заранее, какой это тип?(Я имею в виду, мы знаем, что это тип А, вот и все)

Спасибо за чтение!

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Поскольку вы не хотите, чтобы Q знал о B и C, вы должны хранить A косвенно с помощью указателя, поскольку вы не можете знать, сколько памяти B, C илипотребуется еще неизвестный производный класс D.Классическое решение для одного объекта, который динамически размещается и принадлежит Q: std::unique_ptr.

Поскольку std::unique_ptr по умолчанию использует delete для удаления объекта, вы такженужен виртуальный деструктор в A.

#include"A.hpp"
#include<memory>

class Q {
    std::unique_ptr<A> a;
public:
    Q(std::unique_ptr<A> ai) : a{std::move(ai)} {}
};

Если вы не хотите эксклюзивного владения Q над A или не хотите предоставлять виртуальный деструктор, вы также можете использовать std::shared_ptr.Общие указатели динамически запоминают сохраненный класс и, таким образом, корректно уничтожают объект, если они созданы соответствующим образом, особенно с помощью std::make_shared<MostDerivedClass>.Также они используют подсчет ссылок и будут удалять объект только после того, как все ссылки на объект будут удалены.Недостатком является то, что требуется немного дополнительной памяти и некоторые затраты времени выполнения по сравнению с std :: unique_ptr, который обычно не требует дополнительных затрат по сравнению с простым указателем.

0 голосов
/ 30 мая 2018

Класс должен точно знать тип всех своих подобъектов.Динамический полиморфизм возможен только через косвенность.Таким образом, хотя невозможно содержать объект полиморфного типа, возможно владеть одним.Пример:

struct Q {
    shared_ptr<A> object; // could point to B or C
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...