0

So, here is an example of a class I'm creating :

typedef struct st{
    int counter;
    int fields[128];
}stEx;

class Foo {
    stEx *E;
    int index;
public : 
    Foo(){
        this->index = 0;
        this->E = new stEx;
    }
    ~Foo(){
        delete E;
    }
}

Since I want E to be the instance of the Foo object alone, the E object has to be destroyed automatically when the Foo object gets destroyed, and should'nt therefore outlive that object. That's how I came across the notion of smart pointers, and unique pointers in particular.

However, I can't seem to understand why I need to use unique pointers. And how do I destroy/free a unique pointer?

Here is my attempt with unique pointers.

#include <memory>

typedef struct st{
    int counter;
    int fields[128];
}stEx;

class Foo {
    std::unique_ptr<stEx> E;
    int index;
public : 
    Foo(){
        this->index = 0;
        this->E = std::unique_ptr<stEx>(new stEx());
    }
    ~Foo(){
        E.release; // ?
    }
}

Thanks in advance!

  • 2
    Using `release` would defeat the purpose. The purpose of a `unique_ptr` is to remove the burden to remember to free the resource. [`std::unique_ptr::release`](http://en.cppreference.com/w/cpp/memory/unique_ptr/release) does the opposite, calling it is a statement that you do **not** want the object to be automatically deleted. – François Andrieux Apr 05 '17 at 14:55
  • 3
    Consider using `std::make_unique()` instead of using `new`. – François Andrieux Apr 05 '17 at 14:55
  • 5
    Why are you even using a pointer here? Why not make it a normal value member of the class and you then get automatic cleanup. – NathanOliver Apr 05 '17 at 14:56
  • 2
    Try copy constructing or assigning a `Foo` object. – juanchopanza Apr 05 '17 at 14:56
  • If you want to copy construct Foo: see http://stackoverflow.com/questions/16030081/copy-constructor-for-a-class-with-unique-ptr – Hans Olsson Apr 05 '17 at 15:05
  • There is a big difference between "necessary" and "good style". – Christian Hackl Apr 05 '17 at 15:34

4 Answers4

7

The idiomatic way to do this would be:

class Foo
{
    std::unique_ptr<stEx> E;
    int index;
public: 
    Foo() : E(std::make_unique<stEx>()), index(0)
    {}
};
  • use initialization list
  • use make_unique (never type new)
  • don't have a destructor

This type will automatically be move-enabled, but copy-disabled

Jarod42
  • 203,559
  • 14
  • 181
  • 302
John Smith
  • 169
  • 1
  • 4
3

And how do I destroy/free a unique pointer?

You don't. That's the whole point of unique_ptr: Foo::E is destructed along with Foo, and destructs its pointee too. No manual cleanup.

Also, you will almost never have to use release. This function makes the unique_ptr release its pointee, in the sense that it won't destroy it, and you'll have to delete it yourself as before.

Quentin
  • 62,093
  • 7
  • 131
  • 191
1

In this case, I can't see the need to use unique_ptr, because you have only one object, and the life time of it is within the life time of the class, so you can use just a member.

typedef struct st{
    int counter;
    int fields[128];
}stEx;

class Foo {
    stEx E;
    int index;
public : 
    Foo(){
        index = 0;
    }
}

Also you don't need to use the pointer this to access to the class members.

And there is no need to call:

E.release; // ?

The memory allocated with this line:

this->E = std::unique_ptr<stEx>(new stEx());

Plus the overhead of the smart pointer handle, is freed when the smart pointer goes our of scope.

In your case is implicitly in Foo destructor.

Note: unique_ptr::release() Releases the ownership of the managed object If you need that the new stEx object be no longer owned by E. You have to:

Foo* stExPtr = up.release(); //stEx is no longer owned by unique_ptr
delete stExPtr;
Rama
  • 3,222
  • 2
  • 11
  • 26
1

In the destructor, the compiler will automatically insert calls the destructors for all non-static members of the class. So you don't have to add any code for that to happen.

hakos
  • 270
  • 2
  • 9