简体   繁体   English

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

[英]constructor and destructor calls involved in object creation

I am using the following code snippet to compare two methods for creating an object in C++. 我正在使用以下代码片段来比较在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;
}

The output from this code snippet is: 该代码段的输出为:

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

I am using Visual C++ 2010 (compiler version 16.x) and I am compiling the snippet using cl /EHsc /W4 test.cpp . 我正在使用Visual C ++ 2010 (编译器版本16.x),并且正在使用cl /EHsc /W4 test.cpp编译代码段。 In the construction of Foo_2 , I was expecting to see an extra call to the constructor and destructor in order to create a temporary object and a call to the assignment operator in order to assign the temporary object to Foo_2 . 在构建Foo_2 ,我希望看到对构造函数和析构函数的额外调用,以创建一个临时对象,以及对赋值运算符的调用,以将临时对象分配给Foo_2 Can someone explain to me why this is not the case. 有人可以向我解释为什么不是这种情况。 Apologies if I am missing something very obvious here. 抱歉,如果我在这里遗漏了一些非常明显的内容。

There are two forms of initialization available for Foo : Foo有两种初始化形式:

Foo f1;
Foo f2 = Foo();

The first constructs f directly, using the default constructor. 第一个使用默认构造f直接构造f The second constructs a temporary of type Foo , using the default constructor, and copies that temporary into f2 . 第二种使用默认构造函数构造Foo类型的临时对象,并将该临时对象复制到f2 The latter is what you describe as what you expected. 后者就是您所描述的期望。 And you're right, except for one additional rule: if that form of initialization is valid (which it is here; make the copy constructor private and see what happens), the compiler is allowed to "elide" the copy construction and construct f2 directly, just as in the first version. 而且您是对的,除了一条附加规则:如果该初始化形式有效(就在这里;将副本构造函数设为私有,然后看看会发生什么),则允许编译器“删除”副本构造并构造f2直接,就像在第一个版本中一样。 That's what you're seeing. 那就是你所看到的。 The compiler isn't required to elide the copy constructor, but every one I've used recently does. 不需要编译器退出副本构造函数,但是我最近使用的每一个都需要这样做。

Foo Foo_2 = Foo(); is similar to Foo Foo_2(Foo()); 类似于Foo Foo_2(Foo()); . Compiler is smart enough to do this, no assignment operator is being called. 编译器足够聪明,可以执行此操作,不会调用赋值运算符。 BTW, you have a bug in the assignment operator - you return reference to your object instead of copying it. 顺便说一句,您在赋值运算符中有一个错误-您返回对对象的引用而不是复制它。

第一个“本周专家”问题与您的问题有关, http://www.gotw.ca/gotw/001.htm特别是有关编译器优化的说明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM