我想在方法中使用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#中太长了!)
答案 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}}析构函数是无法抛出的,否则你的类可能只会被部分破坏。
就个人而言,我只是如上所述在堆栈上声明它。