【问题标题】:C++ explicit constructor and castC++ 显式构造函数和强制转换
【发布时间】:2015-02-27 15:03:46
【问题描述】:

在《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 对象在哪里?它是由 cmets 指示的通过强制转换创建的临时对象吗?谁能详细告诉我 doSomeWork 函数参数初始化时调用了什么?

【问题讨论】:

  • 想一想:你的“函数式演员表”不只是对Widget的构造函数的调用吗?
  • 这让我很困惑。我认为答案是肯定的。

标签: c++ constructor casting explicit


【解决方案1】:

函数doSomeWork 的参数w 是一个Widget,您已在该行中作为参数创建

doSomeWork(Widget(15));

doSomeWork 期望 Widget 并且已使用您列出的构造函数显式提供了一个。没有使用编译器提供的复制构造函数,因为doSomeWork(const Widget &w) 签名使用按引用传递语义。

只构造了一个对象,尽管可以使用按值传递,并且聪明的现代编译器会将构造推迟到方法的范围内以避免重复构造。

【讨论】:

  • 感谢您的指出,是的,这是通过引用传递的,因此不涉及复制构造函数。所以我能说会发生什么情况是:const Widget& w=Widget(15) 当函数被调用的时候?参数w是用Widget(15)创建的对象初始化的,这里没有生成临时对象。
  • 是的,我只是添加了传递值通常被编译器优化掉。在您发布的代码的情况下,只创建了一个对象。请参阅 stackoverflow.com/questions/24828074/… 了解有关传递引用和右值的讨论
  • 还有一个问题:在这种情况下Widget w=Widget(15);是一个由Widget(15)首先创建的临时对象,然后由复制构造函数初始化w呢?
  • 我认为这取决于编译器的支持,更好的编译器足够聪明,可以将构造推迟到w 的范围内。虽然您的示例显然是为了创建 2 个对象并测试这个想法,但它显然是人工可修复的。编译器优化称为copy_elision en.cppreference.com/w/cpp/language/copy_elision
猜你喜欢
  • 2018-01-12
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-05
  • 2014-07-26
相关资源
最近更新 更多