以下是具有常见错误的"范围锁定"习惯用法的示例:未创建局部变量,因此锁定无效.这段代码在VC++ 2010和Comeau C++在线编译完美无瑕:
class Mutex
{
public:
void lock() {}
};
class ScopedLock
{
public:
ScopedLock() : m_pm(0) {}
ScopedLock(Mutex& m) : m_pm(&m) { m_pm->lock(); }
private:
Mutex* m_pm;
private:
ScopedLock& operator =(const ScopedLock&);
ScopedLock(const ScopedLock&);
};
class X
{
public:
void foo() const
{
ScopedLock(m_mutex);
}
private:
Mutex m_mutex;
};
int main()
{
X x1;
x1.foo();
}
Run Code Online (Sandbox Code Playgroud)
如果注释掉ScopedLock的默认构造函数,则两个编译器都会给出错误:
错误C2512:'ScopedLock':没有合适的默认构造函数可用
(ScopedLock正确使用时,即创建局部变量:ScopedLock guard(m_mutex);,然后编译按预期失败.声明m_mutex为可变修复问题.)
我有两个问题:
为什么X::foo编译?似乎编译器能够const Mutex&以Mutex&某种方式进行转换.
什么角色扮演ScopedLock默认构造函数,所以编译成功了?
谢谢.
更新:我找到了答案.看来该ScopedLock(m_mutex);语句创建了一个m_mutex类型的局部变量ScopedLock.不是暂时的.这就是为什么ScopedLock::ScopedLock需要默认构造函数的原因.
你自己回答了这个问题。
看来 ScopedLock(m_mutex); 语句创建一个 ScopedLock 类型的局部变量 m_mutex
解释可以在标准的第 6.8 节歧义解决中找到:
涉及表达式语句和声明的语法存在歧义:以函数样式显式类型转换 [5.2.3] 作为其最左侧子表达式的表达式语句与第一个声明符以 ( 开头的声明无法区分。在这些情况下,声明就是声明。
该标准随后列出了T(a);一个实际上是声明的声明示例。它相当于T a;
这是臭名昭著的 C++“最令人烦恼的解析”的一种变体。
| 归档时间: |
|
| 查看次数: |
293 次 |
| 最近记录: |