unique_ptr的范围是否恒定?

时间:2011-12-12 11:25:09

标签: c++ logging

我想在方法中使用unique_ptr。我想依靠它在方法的右大括号 中被破坏的事实(如果确实如此)

我之所以要依赖这个事实,是因为我想编写一个简单的日志类来说明它何时进入/退出一个方法,如:

class MethodTracing
{
    string _signature;

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

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

我可以这样使用它:

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

在方法结束时,unique_ptr在方法结束时被销毁(假设它没有被传递),这是真的(并且是一致的)。

我应该注意其他任何隐藏(或其他!)陷阱吗?

更新 正如大多数答案所示,我本可以使用局部变量范围。我用MethodTracing(__FUNCSIG__);尝试了这个,但当然,我没有分配一个局部变量!所以它立即超出了范围。我认为运行时很聪明,但不是,这是我的愚蠢(在C#中太长了!)

5 个答案:

答案 0 :(得分:3)

您不需要这样做 - 依靠自动存储,例如

void myMethod( )
{
  MethodTracing __sig(__FUNCSIG__);

  // do stuff
}

__sig将在函数范围的末尾自动销毁

(是的__sig是不好的形式,如果你愿意,可以称之为其他内容)

答案 1 :(得分:2)

你通常可以依赖它。例外是显式调用terminate()的代码。通常,对象的析构函数在超出范围时被调用(对于局部变量,即方法的结尾)。这是RAII的基础。

答案 2 :(得分:2)

是的,unique_ptr在它创建的作用域的末尾被销毁。但是你不需要unique_ptr来获得这个功能,因为所有的C ++类都有这个功能。您也可以直接创建MethodTracing对象:

void myMethod( )
{
    MethodTracing _(__FUNCSIG__);
    /// ... 
}

答案 3 :(得分:1)

是的,这是真的。但是,当控制流过关闭支撑时,并不一定。这可能是因为它的阻止返回,异常或转出。

但是在调用exit()来终止程序时应该小心。像您独特的ptr这样的本地自动装置将不会被销毁。

答案 4 :(得分:1)

如果你的~MethodTracing析构函数比上面描述的更复杂,你应该确保你的{{1}}析构函数是无法抛出的,否则你的类可能只会被部分破坏。

就个人而言,我只是如上所述在堆栈上声明它。