为什么它甚至可以编译?
struct UE{
UE(bool a = true) { };
// UE(){}; // if UE took no initial args and called below, gcc will complain.
};
class VA {
protected:
UE ue;
public:
VA();
};
VA::VA()
{
ue = new UE(true); // ???why???
// ue = new UE(); // will complain
}
我尝试使用gcc(GCC)4.6.2。 如何为结构指定指针?
答案 0 :(得分:29)
您确实没有将构造函数标记为explicit
,因此可以将其用于隐式转换。
new UE(true)
返回一个指针。所有指针都可以隐式转换为bool
,如果它们非空,则生成true
。 UE
可以隐式构建bool
。因此实际上,new
返回的指针将转换为bool
,使用您的构造函数将其转换为UE
,然后调用UE
的复制赋值运算符。当然,new
分配的内存已泄露。
带回家的消息是:始终将您的单参数构造函数标记为explicit
,除非您确实希望它们可用于隐式转换。通过“单参数构造函数”,我指的是可以使用单个参数调用的构造函数。要么是因为它有一个参数,要么在第一个参数之后有更多和所有参数都有默认参数。
答案 1 :(得分:8)
从bool
的任何指针进行隐式转换。因此,在将指针转换为bool
值
解决此问题的一种方法是使单个参数构造函数显式化。
struct UE{
explicit UE(bool a = true) { };
};
除非明确调用构造函数,否则这将阻止代码编译
答案 2 :(得分:1)
任何标量类型都可以转换为布尔值true或false,具体取决于它的值是否等于零。
在本声明中
ue = new UE(true);
调用编译器复制赋值运算符隐式定义。由于表达式新UE(true)不等于零,因此可以将其隐式转换为布尔值true。 UE类具有转换构造函数
UE(bool a = true);
将bool类型的对象转换为UE类型的对象。
为了防止这种用法,您应该将构造函数定义为显式
explicit UE(bool a = true);
答案 3 :(得分:1)
如果您将构造函数标记为显式,则无效:
explicit UE( bool a = true) { };
这是因为存在从指针到bool的隐式转换,我们可以看到这是允许来自草案C ++标准部分4.12
布尔转换所说的(强调我的):
算术,无范围枚举,指针或成员类型指针的prvalue可以转换为bool类型的prvalue。