禁止创建临时对象

2024-01-12

在调试多线程应用程序中的崩溃时,我终于在以下语句中找到了问题:

CSingleLock(&m_criticalSection, TRUE);

请注意,它正在创建 CSingleLock 类的未命名对象,因此临界区对象在此语句之后立即解锁。这显然不是程序员想要的。这个错误是由一个简单的打字错误引起的。我的问题是,是否可以通过某种方式阻止在编译时创建类的临时对象,即上述类型的代码应该生成编译器错误。一般来说,我认为每当一个类尝试进行某种资源获取时,就不应该允许该类的临时对象。有什么办法可以强制执行吗?


Edit:正如 j_random_hacker 所指出的,可以强制用户声明一个命名对象以获取锁。

但是,即使您的类以某种方式禁止创建临时对象,用户也可能会犯类似的错误:

// take out a lock:
if (m_multiThreaded)
{
    CSingleLock c(&m_criticalSection, TRUE);
}

// do other stuff, assuming lock is held

最终,用户必须了解他们编写的一行代码的影响。在这种情况下,他们必须知道他们正在创建一个对象,并且必须知道它能持续多久。

另一个可能的错误:

 CSingleLock *c = new CSingleLock(&m_criticalSection, TRUE);

 // do other stuff, don't call delete on c...

这会导致您问“有什么方法可以阻止我的类的用户在堆上分配它”吗?答案是一样的。

在 C++0x 中,还有另一种方法可以完成这一切,即使用 lambda。定义一个函数:

template <class TLock, class TLockedOperation>
void WithLock(TLock *lock, const TLockedOperation &op)
{
    CSingleLock c(lock, TRUE);
    op();
}

该函数捕获了 CSingleLock 的正确用法。现在让用户这样做:

WithLock(&m_criticalSection, 
[&] {
        // do stuff, lock is held in this context.
    });

这对于用户来说更难搞砸。语法一开始看起来很奇怪,但是 [&] 后面跟着一个代码块意味着“定义一个不带参数的函数,如果我通过名称引用任何东西,并且它是外部东西的名称(例如,包含的局部变量)函数)让我通过非常量引用访问它,这样我就可以修改它。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

禁止创建临时对象 的相关文章

随机推荐