C++ 显式构造函数和类型转换

4
在《Effective C++》一书中,第27条建议。
class Widget {
public:
explicit Widget(int size);
...
};
void doSomeWork(const Widget& w);
doSomeWork(Widget(15)); // create Widget from int
                        // with function-style cast

我不确定当调用doSomeWork函数时发生了什么。我想函数doSomeWork的参数w是通过另一个Widget对象使用复制构造函数进行初始化的,但是其他Widget对象在哪里?它是否是由注释所示的强制转换创建的临时对象?有人能详细告诉我当doSomeWork函数参数被初始化时发生了什么吗?


想一想:你的“函数式转换”不就是对Widget构造函数的调用吗? - Kane
1
这就是让我困惑的地方。我认为答案是肯定的。 - Sherry He
1个回答

2
函数doSomeWork的参数w是一个Widget,你在代码行中将其作为参数创建了一个Widget(15)。由于doSomeWork(const Widget &w)使用的是引用传递语义,因此不会使用编译器提供的复制构造函数,而是显式地使用了你列出的构造函数来提供一个Widget。尽管可以使用按值传递,但只会构造一个对象,聪明的现代编译器会将其推迟到方法作用域内以避免重复构造。请注意保留HTML标签。

感谢指出,是的这是传递引用,因此不涉及复制构造函数。那么我可以说发生了什么:当调用函数时,参数w被初始化为由Widget(15)创建的对象,这里没有生成临时对象。 - Sherry He
是的,我只是在添加传值方式通常会被编译器优化掉的内容。在您发布的代码中,只创建了一个对象。请参阅https://dev59.com/lGAf5IYBdhLWcg3wSQ8z,了解有关传引用和rvalues的讨论。 - John
还有一个问题:在语句Widget w=Widget(15);中,这种情况下是先创建了一个由Widget(15)构造的临时对象,然后通过复制构造函数初始化w吗? - Sherry He
1
我认为这取决于编译器的支持,更好的编译器足够聪明,可以推迟构造直到w的范围。虽然您的示例显然是刻意制造2个对象并测试此想法,但很明显是人为可修复的。编译器优化称为复制省略http://en.cppreference.com/w/cpp/language/copy_elision - John

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接