If the new
operator was written in a function argument or constructor argument like:
Foo* f = new Foo(new Baz(0, 0));
// how to delete "new Baz(0, 0)"?
delete f;
I know it can be written to:
Baz* b = new Baz(0, 0)
Foo* f = new Foo(b);
delete b;
delete f;
But it became complicated, is there any better way?
Should I do something like this:
Class Foo {
private:
Baz* _b;
public:
Foo(Baz* b) : _b(b) {}
~Foo() {
delete _b;
}
}
// so that when I delete foo will also delete baz;
CodePudding user response:
Following my own recommendation about the rule of zero and using std::unique_ptr
, I would do something like this:
class Foo
{
public:
Foo(int a, int b)
baz_{ std::make_unique<Baz>(a, b) }
{
}
private:
std::unique_ptr<Baz> baz_;
};
And
auto foo = std::make_unique<Foo>(0, 0);
With this the foo
object own its own unique Baz
object.
If you want Foo
to by copyable then use std::shared_ptr
and std::make_shared
instead.
CodePudding user response:
More or less Yes, you should delete an allocated field in the destructor.
If the class has children, make the destructor virtual
.
However you could have passed an existing pointer. And then the field is not owned.
You can use one of the ptr classes, i.e. std::unique_ptr
for the Baz
.
Or defer the deletion to the caller in some form:
Baz* _b; // Or Baz _b.
Foo(const Baz& b) : _b(new Baz(b)) {} // When feasible a copy.
From design point it would