copy constructor,destructor and temporaries

痞子三分冷 提交于 2019-12-25 04:29:10

问题


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..


回答1:


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

Here the compiler is(and can) eliding the copy and will have the same effect as doing:

Test t2;



回答2:


The standard has specific provision permitting - but not requiring - implementations to elide (i.e. 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).



来源:https://stackoverflow.com/questions/32480806/copy-constructor-destructor-and-temporaries

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!