一开始,对这些拷贝构造,赋值构造也是很迷,然后就把这些常见的总结到一起,进行对比。希望对各位有些帮助。
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "A default constructor" << endl; }
A(const A &obj) { cout << "A copy constructor" << endl; }
~A() { cout << "A destroy" << endl; }
A &operator=(const A &s)
{
if (this == &s)
return *this;
cout << "operator left = " << endl;
return *this;
}
A &operator=(A &&s)
{
cout << "operator right = " << endl;
return *this;
}
};
class B
{
public:
B()
{
cout << "B construcor" << endl;
}
A btemp;
A get() { return btemp; }
};
A fun()
{
A temp;
return temp;
}
int main()
{
cout << "--------------part 1 ------------" << endl;
A a1;
a1 = fun(); // 1.对temp对象进行拷贝一个t1拷贝完成后 2.析构temp,然后调用a1的 "=" 运算符,t1作为参数传入
// gcc中是不这样干的,不拷贝生成一个t1,直接调用a1的 "=" 运算符,用temp做参数
cout << "--------------part 2 ------------" << endl;
A a2 = fun(); //微软的编译器:1.直接用fun()里面的temp,调用拷贝构造函数创建a2 2.a2生成后才析构fun()里面的temp
//gcc中不是这样干的,直接把fun()里面的temp作用域提升,扶正成为a2,两个内存地址是一样的
cout << "--------------part 3 ------------" << endl;
cout << "--" << endl;
B b;
cout << "--" << endl;
A a3 = b.get(); // 1.直接用b.get()里面的btemp对象,进行copy构造一个a3,和上面a2一样。
cout << "--------------part 4 ------------" << endl;
A a4;
a4 = b.get(); // 1.通过b.get()里面的btemp对象,copy构造一个对象t,3.构造然后调用 "=" 运算符 3.调用完再析构这个t
cout << "--------------part 5 ------------" << endl;
a3 = a4; // 直接调用a3的 = 运算符
cout << "--------------part 6 ------------" << endl;
A a5;
a5 = A(); // 1.创建匿名对象 2.调用 "=" 运算符 3.再析构匿名对象
cout << "--------------part 7 ------------" << endl;
A a6 = A(); // 等价 A a6();
}
gcc 和微软家的编译器有些不同,上面代码注释有说明。
gcc环境下输出:
--------------part 1 ------------
A default constructor
A default constructor
operator right =
A destroy
--------------part 2 ------------
A default constructor
--------------part 3 ------------
--
A default constructor
B construcor
--
A copy constructor
--------------part 4 ------------
A default constructor
A copy constructor
operator right =
A destroy
--------------part 5 ------------
operator left =
--------------part 6 ------------
A default constructor
A default constructor
operator right =
A destroy
--------------part 7 ------------
A default constructor
A destroy
A destroy
A destroy
A destroy
A destroy
A destroy
A destroy
visual studio 输出:
--------------part 1 ------------
A default constructor
A default constructor
A copy constructor
A destroy
operator right =
A destroy
--------------part 2 ------------
A default constructor
A copy constructor
A destroy
--------------part 3 ------------
--
A default constructor
B construcor
--
A copy constructor
--------------part 4 ------------
A default constructor
A copy constructor
operator right =
A destroy
--------------part 5 ------------
operator left =
--------------part 6 ------------
A default constructor
A default constructor
operator right =
A destroy
--------------part 7 ------------
A default constructor
A destroy
A destroy
A destroy
A destroy
A destroy
A destroy
A destroy