我遇到了一些让我感到惊讶的代码。这在Visual Studio 2012中编译并运行得很好。
class Description {
public:
Description(bool valid = false);
~Description(void);
};
Description functionThatReturnsADescription()
{
return 1;
}
int main()
{
Description theDescription = functionThatReturnsADescription();
}
我的混淆是functionThatReturnsADescription()
方法;返回除Description之外的任何对象是否合法?如果我将其设置为return 1
,则会使用valid = true
调用Description构造函数。如果我将其设置为return false
或return 0
,则会使用valid = false
调用描述构造函数。
这是否意味着C ++编译器总是使用return语句的参数调用函数的返回类型构造函数?我以前怎么不知道?!我会发誓这不是合法的C ++。
答案 0 :(得分:3)
返回除Description之外的任何对象是否合法?
您可以返回任何可隐式转换为Description
的类型。在这种情况下,任何数字类型都可以通过标准转换转换为bool
,然后通过非显式构造函数转换为Description
。
如果您愿意,可以通过声明构造函数explicit
来阻止此转换。让这个习惯成为一个好主意,以避免像这样的意外转换。
这是否意味着C ++编译器总是使用return语句的参数调用函数的返回类型构造函数?
如果类型不匹配,并且有一个合适的非显式构造函数用于转换,是的。
我以前怎么不知道?!
C ++是一门复杂的语言。十五年后,我仍然在寻找我不知道的事情。
答案 1 :(得分:1)
1
被隐式转换为true
,因此选择接受bool
的构造函数。
要阻止此隐式转换,您可以将构造函数标记为explicit
,在这种情况下只能
return Description(1);
会起作用。
答案 2 :(得分:1)
返回值1
被隐式转换为boolean true
,然后作为参数传递给构造函数。使用构造函数Description
隐式创建Description(bool valid = false);
对象。
需要注意的是,这里发生了两次隐式转换:1→true→描述。您可以通过构造函数explicit
来阻止第二次转换。将构造函数的声明更改为
explicit Description(bool valid = false);
然而,第一次转换仍然会发生,即仍然可以进行return Description(1);
。