0

我遇到了一些令我惊讶的代码。这在 Visual Studio 2012 中编译并且运行良好。

描述类

class Description {
public:
    Description(bool valid = false);
    ~Description(void);
};

主要的

Description functionThatReturnsADescription()
{
    return 1;
}

int main()
{
    Description theDescription = functionThatReturnsADescription();
}

我的困惑在于functionThatReturnsADescription()方法;返回描述以外的任何对象是合法的吗?如果我将其设置为return 1,它会使用 调用 Description 构造函数valid = true。如果我将它设置为return falseor return 0,它会使用 . 调用 Description 构造函数valid = false

这是否意味着 C++ 编译器总是使用 return 语句的参数调用函数的返回类型构造函数?我以前怎么不知道?!我会发誓这不是合法的 C++。

4

3 回答 3

3

返回描述以外的任何对象是合法的吗?

您可以返回任何可隐式转换为Description. 在这种情况下,任何数字类型都可以bool通过标准转换转换为,然后Description通过非显式构造函数转换为。

如果您愿意,可以通过声明构造函数来阻止这种转换explicit。养成这种习惯是个好主意,以避免像这样的意外转换。

这是否意味着 C++ 编译器总是使用 return 语句的参数调用函数的返回类型构造函数?

如果类型不匹配,并且有一个合适的非显式构造函数用于转换,是的。

我以前怎么不知道?!

C++ 是一门复杂的语言。十五年后,我仍然不断地发现我不知道的东西。

于 2013-09-27T09:56:59.340 回答
1

1隐式转换为true,因此选择了接受 a 的构造函数bool

为了防止这种隐式转换,您可以将构造函数标记为explicit,仅在这种情况下

return Description(1);

会工作。

于 2013-09-27T09:55:52.780 回答
1

返回值1被隐式转换为布尔值true,然后作为参数传递给构造函数。使用Description构造函数隐式创建对象Description(bool valid = false);

需要注意的是,这里发生了两个隐式转换:1 → true → 描述。您可以通过构造构造函数来防止第二次转换explicit。将构造函数的声明更改为

explicit Description(bool valid = false);

但是,第一次转换仍然会发生,即仍然可以进行return Description(1);

参考:C++ 中的显式关键字是什么意思?

于 2013-09-27T09:56:25.327 回答