Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

destructor and unique_ptr

Tags:

I have the following code

class A {     public:         A(){}         ~A(){}     private:         std::vector<std::unique_ptr<double> > x; };  A f() {     A a;     return a; }  int main() {     A a=f();     return 0; } 

It does not compile (gcc 4.7), unless I comment out the destructor. Actually, I don't really need this destructor in my code, I just wanted to use it for debug purpose.

However, I don't understand what is happening and I therefore fear I have done something wrong. What is happening here ?

like image 638
Bérenger Avatar asked Mar 18 '13 20:03

Bérenger


People also ask

Does unique_ptr call destructor?

Yes. Well the unique ptr has a function object that by default invokes delete on the pointed to object, which calls the destructor. You can change the type of that default deleter to do almost anything.

What is a unique_ptr?

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.

Should I delete unique_ptr?

An explicit delete for a unique_ptr would be reset() . But do remember that unique_ptr are there so that you don't have to manage directly the memory they hold. That is, you should know that a unique_ptr will safely delete its underlying raw pointer once it goes out of scope.

What is the difference between Auto_ptr and unique_ptr?

As for other differences, unique_ptr can handle arrays correctly (it will call delete[] , while auto_ptr will attempt to call delete .


1 Answers

That is because the presence of an explicitly defined destructor prevents the implicit generation of a move constructor for A.

Per Paragraph 12.8/9 of the C++11 Standard:

If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if

— X does not have a user-declared copy constructor,

— X does not have a user-declared copy assignment operator,

— X does not have a user-declared move assignment operator,

X does not have a user-declared destructor, and

— the move constructor would not be implicitly defined as deleted.

Now without a move constructor, to return the value from f() the compiler will try to invoke the implicitly generated copy constructor (which is still being generated for backwards compatibility). However, std::unique_ptr is non-copyable. Hence, the error.

Explicitly defining a move constructor (or declaring one as defaulted, as suggested by juanchopanza in the comments) will fix the problem.

like image 69
Andy Prowl Avatar answered Oct 11 '22 12:10

Andy Prowl