简体   繁体   English

复制构造函数,析构函数和临时函数

[英]copy constructor,destructor and temporaries

I wrote this class to test the behaviour of the default constructor,the copy constructor, the assignment operator and the destructor: 我编写了此类,以测试默认构造函数,副本构造函数,赋值运算符和析构函数的行为:

#include <iostream>

class Test {

  public:
    Test();

    Test(const Test&);

    ~Test();

    Test &operator=(const Test&);

  private:
    static int count;
    int label;

};

Test::Test() : label(count++) 
{
  std::cout<<"constructor of "<<label<<std::endl;
}

Test::Test(const Test &other) : label(count++)
{
  std::cout<<"copy-constructor of "<<label<<std::endl;
}

Test::~Test()
{
  std::cout<<"destructor of "<<label<<std::endl;
}

Test &Test::operator=(const Test &other)
{
  std::cout<<"copy assignment operator of "<<label<<std::endl;
}

int Test::count=0;

I used this class in diferent contextes to deeply understand how and when each function is called: I expect the behaviour in the comments: 我在不同的上下文中使用了此类,以深刻理解每个函数的调用方式和时间:我期望注释中的行为:

#include "Test.h"



// argument passed and returned by reference 
const Test &funct_by_ref(const Test &ref)
{
  return ref;
}

// argument passed and returned by value
// call copy constructor to initialize parameter
Test funct_by_val(Test val)
{
  // calls copy constructor to initialize temporary
  return val;
}  // exits local scope,val is destroyed,calls val destructor 



int main()
{
  // creates a temporary,calls 0 default constructor 
  Test();  // the temporary is destroyed at the end of the expression that created it
           // calls 0 destructor
  // creates a temporary (calls 1 default constructor) and calls 2 copy constructor 
  Test t2=Test(); // same as Test t2((Test()));
  std::cout<<"--------------------------------"<<std::endl;
  // calls 3 copy constructor
  Test t3=t2;
  // calls 4 default constructor
  Test t4;
  {
    // calls 5 copy constructor
    Test t5(t4);
  } // local scope,t5 is destroyed,calls 5 destructor
  // calls 4 assignment operator 
  t4=t2;
  std::cout<<"-------------------------------"<<std::endl;
  // nothing happens here
  funct_by_ref(t4);
  std::cout<<"-------------------------------"<<std::endl;
  // calls copy constructor twice 6,7
  funct_by_val(t4);
  // temporary is destroyed at the end of the expression,calls destructor
}

but instead I get the following output: 但是我得到以下输出:

constructor of 0
destructor of 0
constructor of 1
------------------------
copy-constructor of 2
constructor of 3
copy-constructor of 4
destructor of 4
copy assignment operator of 3
--------------------------
---------------------------
copy-constructor of 5
copy-constructor of 6
destructor of 6
destructor of 5
destructor of 3
destructor of 2
destructor of 1

all is fine until the first ----------------- where it seems to skip the creation of an object (I think of the temporary uset to initialize t2, because it's not destroyed right after that line) and so the count is off by one.. 一切都很好,直到第一个-----------------那里似乎跳过了对象的创建(我想到了临时用例来初始化t2,因为它不会在之后立即销毁该行),因此计数相减一。

Test t2=Test(); // same as Test t2((Test()));

在这里,编译器可以(并且可以) 删除副本,并且效果与这样做相同:

Test t2;

The standard has specific provision permitting - but not requiring - implementations to elide (ie omit the creation of) temporaries, if the only way to detect their existence is by tracking constructor and destructor calls. 如果唯一的检测方式是通过跟踪构造函数和析构函数调用来检测临时对象的存在,则该标准具有特定的规定,允许(但不要求)实现消除临时对象(即省略临时对象的创建)。

The discrepancies you see are because the behaviours you anticipate are based on the creation and destruction of temporaries, and the compiler is electing to not create those temporaries. 您看到的差异是因为您预期的行为是基于临时对象的创建和销毁,并且编译器选择不创建那些临时对象。 Note that decisions to elide temporaries vary are implementation dependent (and often affected by optimisation settings). 请注意,更改临时人员的决定会因实现而异(并且通常会受到优化设置的影响)。

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

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