What about following code
MyClass a(new Foo(), new Bar());
if "new Foo()" is successful, but "new Bar()" throws, will Foo leak?
Is taking
std::unique_ptr<Foo>
or
std::shared_ptr<Foo>
as parameters, enough to prevent the leak?
The short answer to the question “can a constructor throw an exception in Java” is yes!
When throwing an exception in a constructor, the memory for the object itself has already been allocated by the time the constructor is called. So, the compiler will automatically deallocate the memory occupied by the object after the exception is thrown.
In C++, exceptions are used to signal errors that cannot be handled locally, such as the failure to acquire a resource in a constructor.
When an exception is thrown from a constructor, the object is not considered instantiated, and therefore its destructor will not be called. But all destructors of already successfully constructed base and member objects of the same master object will be called.
if "new Foo()" is successful, but "new Bar()" throws, does Foo will leak?
Yes.
Is taking [...] as parameters, enough to prevent the leak?
Not necessarily. It depends on how you pass the parameters. For instance, even supposed your class constructor looks like this:
MyClass::MyClass(std::unique_ptr<Foo> foo, std::unique_ptr<Bar> bar)
The following may still cause a leak:
MyClass a(std::unique_ptr<Foo>(new Foo()), std::unique_ptr<Bar>(new Bar())
That is because the compiler may is allowed to evaluate the above expressions in the following order:
new Foo()
new Bar()
std::unique_ptr<Foo>
temporary from the result of 1.std::unique_ptr<Bar>
temporary from the result of 2.If 2) throws an exception, you've lost your Foo
.
However, it is possible to make this safe by using std::make_unique<>()
(C++14 only) or std::make_shared<>()
, like so:
MyClass a(std::make_unique<Foo>(), std::make_unique<Bar>());
Now no leak could possibly happen, because std::make_unique<>()
(and std::make_shared<>()
) immediately associate the object they create to the corresponding smart pointer, without these two operations (dynamic allocation and construction of the smart pointer) being interleaved with any other operation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With