对象创建中涉及的构造函数和析构函数调用

时间:2012-10-24 17:37:58

标签: c++ default-constructor

我使用以下代码片段来比较在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 。有人可以向我解释为什么不是这种情况。如果我遗漏了一些非常明显的东西,请道歉。

3 个答案:

答案 0 :(得分:4)

Foo有两种初始化形式:

Foo f1;
Foo f2 = Foo();

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

答案 1 :(得分:1)

Foo Foo_2 = Foo();Foo Foo_2(Foo());类似。编译器足够智能,不会调用赋值运算符。顺便说一下,你在赋值运算符中有一个错误 - 你返回对象的引用而不是复制它。

答案 2 :(得分:1)

本周的第一个&#34;大师&#34;问题只是关于你的问题http://www.gotw.ca/gotw/001.htm 特别是编译器优化的注意事项。