Как избежать двойного удаления указателя, когда два класса совместно используют один и тот же объект кучи?

Как избежать двойного удаления указателя, когда два класса совместно используют один и тот же объект кучи? Я столкнулся с такой проблемой: два больших объекта класса совместно используют один большой объект. Инициализируются в исходной функции. Потому что он большой, поэтому я не хочу их копировать. Я размещаю их в куче и сохраняю указатель:

class A {
public:
A(C* in_p) : p(in_p){}
~A() {delete p;}
private:
C* p;
}
class B {
public:
B(C* in_p) : p(in_p){}
~B(){delete p;}
private:
C* p;
}
class C {
public:
~C() {...}
}
void initial(A* pa, B* pb) {
C* a = new C;
C* b = a;
pa = new A(a);
pb = new B(b);
... some other initialization codes
}
int main() {
A* pa = nullptr;;
B* pb = nullptr;
initial(pa, pb);
........ some processing codes
//clear up
delete pa;
delete pb;
}

Но когда я их убираю, проблема возникает после Aразрушение, C экземпляр класса не в куче. затем BДеструктор удаляю ту же кучу области, и вызываю Cдеструктор грохнулся Cуказатель туда и позвони C->destructor потерпит крах. Б не знает C уже не существует после A будучи удаленным, и Bчлен (C*)p не изменится, когда A разрушает свою собственную (C*)p,

Я не могу ни пройти C* p по ссылке или пасс C** связывать A«s p а также B«s pпосле initial() закончить, локальные переменные стека C*(a) C*(b) не будет больше там. Так после initial(), A«s (C**)p а также B«s (C**)p будет хранить неизвестный адрес памяти, и он будет зависать при их использовании.

Итак, как вы справляетесь с этой ситуацией в традиционной сборке мусора, управляемой пользователем C ++, до того, как вышел интеллектуальный указатель?

0

Решение

использование std::shared_ptr, Если у вас его нет, используйте boost::shared_ptr, Если вы не можете использовать его, напишите свой собственный, основываясь на дизайне Boost. Если вашему компилятору C ++ не исполнилось десятилетия, я не вижу причин, по которым вы не можете использовать один из этих трех вариантов.

2

Другие решения


По вопросам рекламы [email protected]