Say I have two classes:
"Foo.h"
#pragma once
class Foo
{
public:
Foo()
{
};
~Foo()
{
};
};
"A.h"
#pragma once
#include <memory>
class Foo;
class A
{
public:
A(){};
~A(){};
std::unique_ptr<Foo> foo;
};
A holds a unique_ptr
of Foo
. I didn't want to include Foo
in "A.h", so I forward declared it. By just forward declaring the class Foo
in "A.h", I get a compile time error:
error C2027: use of undefined type 'Foo'
error C2338: can't delete an incomplete type
So I was following this article on how to avoid this error and moved A's destructor in it's own .cpp file where I also include Foo:
"A.cpp"
#include "A.h"
#include "Foo.h"
A::A()
{
}
A::~A()
{
}
After implementing the destructor of A in "A.cpp", I'm able to compile the program, because the class Foo is known in "A.cpp". This seems logical, because unique_ptr needs the complete type to call it's destructor. But to my surprise, after commenting out the constructor of A (in "A.h" as well as "A.cpp"), I get the same error. How is this possible? Why does the compiler complain about beeing not able to call Foo's destructor when A has no constructor?
EDIT: I uploaded the 4 files so you can test the program. I'm using MSVC++ of Visual Studio 2013.
http://www.filedropper.com/test_61
(since C++11) std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.
Forward Declaration refers to the beforehand declaration of the syntax or signature of an identifier, variable, function, class, etc. prior to its usage (done later in the program). Example: // Forward Declaration of the sum() void sum(int, int); // Usage of the sum void sum(int a, int b) { // Body }
In computer programming, a forward declaration is a declaration of an identifier (denoting an entity such as a type, a variable, a constant, or a function) for which the programmer has not yet given a complete definition.
A unique_ptr does not share its pointer. It cannot be copied to another unique_ptr , passed by value to a function, or used in any C++ Standard Library algorithm that requires copies to be made. A unique_ptr can only be moved.
The constructor needs access to the deleter in just the same way the destructor does: exception safety requires that the constructor be able to roll-back initialisation of all the members in the case that your constructor's body throws:
[C++14: 12.6.2/10]:
In a non-delegating constructor, the destructor for each potentially constructed subobject of class type is potentially invoked (12.4). [ Note: This provision ensures that destructors can be called for fully-constructed sub-objects in case an exception is thrown (15.2). —end note ]
Related:
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