拷贝构造函数、析构函数和临时变量
copy constructor,destructor and temporaries
我写这个class是为了测试默认构造函数、复制构造函数、赋值运算符和析构函数的行为:
#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;
我在不同的上下文中使用这个 class 来深入理解每个函数的调用方式和时间:我希望评论中的行为:
#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
}
但我得到以下输出:
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
一切都很好,直到第一个 ----------------- 它似乎跳过了对象的创建(我想到了初始化 t2 的临时用途,因为它并没有在该行之后立即被销毁)所以计数减一..
Test t2=Test(); // same as Test t2((Test()));
这里的编译器是(并且可以)eliding the copy 并且将具有与以下操作相同的效果:
Test t2;
如果检测临时对象存在的唯一方法是跟踪构造函数和析构函数调用,则该标准有特定条款允许 - 但不要求 - 实现省略(即省略创建)临时对象。
您看到的差异是因为您预期的行为是基于临时对象的创建和销毁,而编译器选择不创建这些临时对象。请注意,消除临时变量的决定取决于实现(并且通常受优化设置影响)。
我写这个class是为了测试默认构造函数、复制构造函数、赋值运算符和析构函数的行为:
#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;
我在不同的上下文中使用这个 class 来深入理解每个函数的调用方式和时间:我希望评论中的行为:
#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
}
但我得到以下输出:
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
一切都很好,直到第一个 ----------------- 它似乎跳过了对象的创建(我想到了初始化 t2 的临时用途,因为它并没有在该行之后立即被销毁)所以计数减一..
Test t2=Test(); // same as Test t2((Test()));
这里的编译器是(并且可以)eliding the copy 并且将具有与以下操作相同的效果:
Test t2;
如果检测临时对象存在的唯一方法是跟踪构造函数和析构函数调用,则该标准有特定条款允许 - 但不要求 - 实现省略(即省略创建)临时对象。
您看到的差异是因为您预期的行为是基于临时对象的创建和销毁,而编译器选择不创建这些临时对象。请注意,消除临时变量的决定取决于实现(并且通常受优化设置影响)。