Каков наилучший подход для инкапсуляции объектов и управления их временем жизни? Пример: у меня есть класс A , который содержит объект типа B и несет ответственность за него .
Решение 1 , клон b объекта, чтобы гарантировать, что только A может очистить его.
class A
{
B *b;
public:
A(B &b)
{
this->b = b.clone();
}
~A()
{
delete b; // safe
}
};
Решение 2 , напрямую используйте переданный объект, мы рискуем получить здесь потенциальную двойную свободу.
class A
{
B *b;
public:
A(B *b)
{
this->b = b;
}
~A()
{
delete b; // unsafe
}
};
В моем случае решение № 2 подошло бы лучше всего. Однако мне интересно, считается ли это плохим кодом, потому что кто-то может не знать о поведении A , даже если это задокументировано. Я могу думать об этих сценариях:
B *myB = new B();
A *myA = new A(myB);
delete myB; // myA contains a wild pointer now
Или,
B *myB = new B();
A *firstA = new A(myB);
A *secondA = new A(myB); // bug! double assignment
delete firstA; // deletes myB, secondA contains a wild pointer now
delete secondA; // deletes myB again, double free
Могу ли я просто игнорировать эти проблемы, если правильно документирую поведение A? Достаточно ли объявить об ответственности и предоставить остальным возможность читать документы? Как это управляется в вашей кодовой базе?