Как избежать двойного удаления указателя, когда два класса совместно используют один и тот же объект кучи? Я столкнулся с такой проблемой: два больших объекта класса совместно используют один большой объект. Инициализируются в исходной функции. Потому что он большой, поэтому я не хочу их копировать. Я размещаю их в куче и сохраняю указатель:
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 ++, до того, как вышел интеллектуальный указатель?
использование std::shared_ptr
, Если у вас его нет, используйте boost::shared_ptr
, Если вы не можете использовать его, напишите свой собственный, основываясь на дизайне Boost. Если вашему компилятору C ++ не исполнилось десятилетия, я не вижу причин, по которым вы не можете использовать один из этих трех вариантов.