Поскольку вы не хотите, чтобы 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, который обычно не требует дополнительных затрат по сравнению с простым указателем.