2

我正在使用以下代码片段来比较在 C++ 中创建对象的两种方法。

#include <iostream>

using std::cout;
using std::endl;

class Foo {
    public:
        Foo() : x(0) { cout << "In Foo constructor." << endl; }
        ~Foo() { cout << "In Foo destructor." << endl; }
        Foo(const Foo&) { cout << "In Foo copy constructor." << endl; }

        // Assignment operator.
        Foo& operator=(const Foo&) {
            cout << "In assignment operator." << endl;
            return *this;
        }

    private:
        int x;
};

int main() {

    cout << "Constructing Foo 1" << endl;
    Foo Foo_1;
    cout << "Constructing Foo 2" << endl;
    Foo Foo_2 = Foo();

    return 0;
}

此代码段的输出是:

  Constructing Foo 1
  In Foo constructor.
  Constructing Foo 2
  In Foo constructor.
  In Foo destructor.
  In Foo destructor.

我正在使用Visual C++ 2010(编译器版本 16.x),我正在使用cl /EHsc /W4 test.cpp. 在. Foo_2_ Foo_2有人可以向我解释为什么不是这样。抱歉,如果我在这里遗漏了一些非常明显的东西。

4

3 回答 3

4

有两种初始化形式可用于Foo

Foo f1;
Foo f2 = Foo();

第一个f直接构造,使用默认构造函数。第二个Foo使用默认构造函数构造一个临时类型,并将该临时复制到f2. 后者就是您所描述的您所期望的。你是对的,除了一个额外的规则:如果这种形式的初始化是有效的(它在这里;将复制构造函数设为私有,看看会发生什么),编译器可以“省略”复制构造并f2直接构造,就像在第一个版本中一样。这就是你所看到的。编译器不需要省略复制构造函数,但我最近使用的每一个都需要。

于 2012-10-24T17:48:20.663 回答
1

Foo Foo_2 = Foo();类似于Foo Foo_2(Foo());。编译器足够聪明地做到这一点,没有调用赋值运算符。顺便说一句,您在赋值运算符中有一个错误-您返回对对象的引用而不是复制它。

于 2012-10-24T17:42:42.660 回答
1

第一个“本周大师”问题只是关于您的问题http://www.gotw.ca/gotw/001.htm 特别是关于编译器优化的说明。

于 2012-10-24T18:04:06.520 回答