У меня есть объект, содержащий список экземпляров абстрактного класса.Как вы возвращаете объект, который принимает чистые виртуальные (const ref) аргументы в C++?
class A { }; // abstract class
class B {
public:
void addA(const A& a) {
list_of_a_.push_back(&a);
}
private:
std::vector<const A*> list_of_a_;
};
A является абстрактным, поэтому я храню их в векторе в качестве указателей и передавая его в качестве ссылки на константу. У меня есть разные подклассы A.
Тогда у меня есть заводская функция, которая создает B и возвращает ее.
B CreateB() {
B b;
DerivationOfA a; // subclass of abstract class A.
b.addA(a);
return b;
}
int main() {
B b = CreateB();
b.DoSomethingWithA(); // bad memory, 'a' was destroyed.
}
Проблема возникает после того, как функция B возвращается из функции «create», экземпляр A уничтожается в стеке. То же самое происходит, когда я использую умный указатель. Я хочу избежать использования обычных указателей, чтобы избежать дополнительных проблем с управлением памятью.
Есть ли уловка для этого, чтобы я мог сохранить функцию CreateB
, избегайте использования указателей, но все же сможете передавать абстрактные классы в B
? Я в порядке с использованием pass по значению, просто C++ не позволяет делать это с абстрактными классами.
Редактировать: Я знаю, почему это происходит, но я не уверен, как обойти его при использовании чистых виртуальных объектов. Вне использования C-указателей, которых я хочу избежать, я не уверен, как избежать проблемы с определением области охвата.
Edit 2: Чистые виртуальные классы вместо объектов быть более точным.
Edit 3: Аннотация классов вместо чисто виртуальных классов для удовлетворения придирки.
Это не имеет ничего общего с виртуальными функциями или абстрактными классами, но все, что вы храните указатели на локальные переменные. Подумайте об использовании указателей полностью, если у вас есть абстрактные базовые классы, а затем подумайте о владении указателем и о том, как их можно управлять с помощью интеллектуальных указателей. –
нет такого понятия, как «чистый виртуальный объект». Термин «чистый виртуальный класс» можно перевести как «класс, который не может быть инстанцирован», т. Е. Вы не можете создать объект этого класса. – user463035818
Вам нужно «новое» вверх 'DerivationOfA' (или, может быть,' make_unique' или 'make_shared', если вы предпочтете, что внутренне собираются в конечном итоге делать «новые» между прочим). Нет никакого способа обойти это, потому что вы не можете указывать указатели на локальные переменные, и вы не можете делать ничего подобного вектору , поддерживая производные классы. – TheUndeadFish