2013-03-06 30 views
-1

我在我们的软件中遇到了这样一段代码,它依靠析构函数释放一个锁。然而,当我运行程序时,析构函数永远不会被调用,并且锁定永远不会被释放。我们可以依靠析构函数多少?

bool someClass::someFunc() 
{ 
    Locker lock(m_lock); //take lock in constructor, release lock in Locker destructor 
    return something; 
} 

这里怎么回事?编译器可以优化这个函数是否内联?

class Locker { 
    public: 
     Locker(Lock& lock) : m_lock(lock) { m_lock.lock(); } 
    ~Locker() { m_lock.unlock(); } 
    protected: 
    Lock& m_lock; 
} 
+8

你怎么知道析构函数从来没有被调用过?你可以给一个完整的,最小的repro? – SirPentor 2013-03-06 01:58:55

+2

除非你的程序使用特殊的系统调用来退出(例如'_exit()'),这几乎是不可能的,因为[C++是RAII之王](http://lazarenko.me/2013/03/03/automatic-资源管理/)。请发布一个演示问题的最小工作代码示例。 – 2013-03-06 01:59:16

+3

这是基本的RAII,析构函数会被调用.. – 2013-03-06 01:59:28

回答

2

你确定Locker实际上释放了析构函数中的锁吗?除非程序崩溃或中止或出现其他异常情况,否则您可以指望被调用的析构函数。也许你的调试器显示错误的值?

如果编译器优化它的内联,代码仍然会被执行。 “内联”并不意味着代码永远不会运行。

+0

类锁柜 { public: 更衣柜(锁定和锁定):m_lock(锁定){m_lock.lock(); } 〜Locker(){m_lock.unlock();} } protected: Lock&m_lock; – ddahuja 2013-03-06 02:04:22

+0

你有什么迹象表明它没有被解锁?有时你的调试器显示不准确的信息 - 你能否在析构函数中输出一些文本来测试它是否被调用? C++ *应该*调用那个析构函数。 – 2013-03-06 02:07:16

+1

我唯一的疑问是,如果内联会阻止对象超出范围,那么即使内联析构函数被调用,我也会通过小例子进行验证。所以更多的业务逻辑调试!谢谢你的答案。 – ddahuja 2013-03-06 02:43:20

2

我怀疑你的意见,析构函数没有被调用是错误的。以下是如何一劳永逸地证明这一点:

#include<iostream> 

class Locker { 
    public: 
     Locker(Lock& lock) : m_lock(lock) { m_lock.lock(); std::cout<<"locked\n"; } 
    ~Locker() { m_lock.unlock(); std::cout<<"unlocked\n"; } 
    protected: 
    Lock& m_lock; 
} 

Ofcourse,这只是为了满足自己的析构函数被调用。不要在那里留下线:)

相关问题