0

I want to use unique_ptr in a method. I want to rely on the fact that it is destroyed at the closing brace of the method (if that is indeed true).

The reason why I want to rely on this fact is that I want to write a simple class for logging that says when it has entered/exited a method, something like:

class MethodTracing
{
    string _signature;

    public:
        MethodTracing(string signature)
        {
            _signature=signature;
            BOOST_LOG_TRIVIAL(trace) << "ENTERED " << _signature ;
        }

        ~MethodTracing()
        {
            BOOST_LOG_TRIVIAL(trace) << "EXITED " << _signature;
        }
};

I can then use it like so:

void myMethod( )
{
    auto _ = unique_ptr<MethodTracing>(new MethodTracing(__FUNCSIG__) ) ;
    /// ... 
}

Is it true (and consistent) that a unique_ptr, when created in a method, is destroyed at the end of the method (assuming it's not passed around).

Are there any other hidden (or otherwise!) pitfalls that I should be aware of?

Update: As most of the answers suggested, I could have used local variable scoping. I tried this with MethodTracing(__FUNCSIG__);, but of course, I didn't assign a local variable! so it immediately went out of scope. I thought the runtime was being clever, but no, it was me being stupid (too long in C#!)

Steve Dunn
  • 21,044
  • 11
  • 62
  • 87

5 Answers5

3

You don't need to do that - rely on automatic storage, e.g.

void myMethod( )
{
  MethodTracing __sig(__FUNCSIG__);

  // do stuff
}

__sig will be destroyed at the end of the function scope automatically

(yes __sig is bad form, call it something else if you want)

Nim
  • 33,299
  • 2
  • 62
  • 101
2

You can usually rely on it. The exception would be code that explicitly calls terminate(). In general, destructors of objects are called when they go out of scope (for local variables, that is the end of the method). This is the foundation of RAII.

Community
  • 1
  • 1
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
  • 3
    Any function which neither returns nor throws an exception will cause this: `exit()`, `abort()`, `terminate()` and some cases of `raise()`; destructors can also be skipped by `longjmp()`, but no C++ program should use this function. In general, C++ programs should not use `exit()`, either, and the other cases represent abnormal program terminations, where it is generally acceptable (and often preferable) to not call destructors. – James Kanze Dec 12 '11 at 11:40
2

Yes, unique_ptr is destroyed at the end of the scope it's created in. However you don't need unique_ptr to get this functionality, because all C++ classes have this. You might as well just create your MethodTracing object directly:

void myMethod( )
{
    MethodTracing _(__FUNCSIG__);
    /// ... 
}
bames53
  • 86,085
  • 15
  • 179
  • 244
1

Yes that is true. But it is not necessarily when control flows through the closing brace. It can be because of a return, an exception or a goto out of its block.

However care should be taken when calling exit() to terminate the program. The local automatics like your unique ptr will no be destroyed then.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
1

You ought to ensure that your ~MethodTracing destructor is no-throw if it is more complex that what you describe above, otherwise your class might only be partially destroyed.

Personally, I'd just declare it on the stack as mentioned above.

Barry
  • 606
  • 7
  • 13