What is the best approach to encapsulate objects and manage their lifetime? Example: I have a class A, that contains an object of type B and is solely responsible for it.
Solution 1, clone b object to ensure that only A is able to clean it up.
class A
{
B *b;
public:
A(B &b)
{
this->b = b.clone();
}
~A()
{
delete b; // safe
}
};
Solution 2, directly use the passed object, we risk a potential double free here.
class A
{
B *b;
public:
A(B *b)
{
this->b = b;
}
~A()
{
delete b; // unsafe
}
};
In my actual case, solution #2 would fit best. However I wonder if this is considered bad code because someone might not know about the behavior of A, even if it's documented. I can think of these scenarios:
B *myB = new B();
A *myA = new A(myB);
delete myB; // myA contains a wild pointer now
or
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
Can I just ignore these issues if I properly document the behavior of A? Is it enough to declare the responsibility and leave it up to the others to read the docs? How is this managed in your codebase?