匿名对象:临时的对象,一般都是在构造完就被释放掉了(有特殊情况,返回值优化)
1. 返回值优化:若是函数返回的匿名对象返回时候有同类型的新对象接上,则该匿名对象被转化为新对象。

1 #include "iostream" 2 using namespace std; 3 4 class A 5 { 6 public: 7 A (int _a=0, int _b=0) 8 { 9 this->a1 = _a; 10 this->b1 = _b; 11 cout << "construct function called!" << endl; 12 } 13 A (A &obj) 14 { 15 cout << "copy_constructor function called!" << endl; 16 } 17 ~A() 18 { 19 cout << "objext destory function called!" << endl; 20 } 21 protected: 22 private: 23 int a1; 24 int b1; 25 }; 26 27 // 函数返回值产生匿名对象 28 A g() 29 { 30 A a2(10,19); 31 return a2; 32 } 33 // 测试一: 匿名对象用来初始化一个新对象。 34 void Test1() 35 { 36 A a1 = g(); 37 } 38 // 测试二: 用等号初始化一个新对象 39 void Test2() 40 { 41 A a3; 42 a3 = g(); 43 } 44 45 int main() 46 { 47 Test1(); 48 Test2(); 49 return 0; 50 }
// Test1结果:调用了两次构造函数,两次析构函数 construct function called!构造a2 copy_constructor function called!构造匿名a2的匿名对象 objext destory function called!析构局部变量a2 objext destory function called!析构a1(其实就是a2的匿名对象) // Test2结果:调用了三次构造函数三次析构函数 construct function called!构造a3 construct function called!构造a2 copy_constructor function called!构造匿名a2的匿名对象 objext destory function called!析构局部变量a2 objext destory function called!析构a2的匿名对象
2. 没有对象名:普通情况,构造完成之后就直接被析构

1 #include "iostream" 2 using namespace std; 3 4 class A 5 { 6 public: 7 A (int _a=0, int _b=0) 8 { 9 this->a1 = _a; 10 this->b1 = _b; 11 cout << "construct function called!" << endl; 12 } 13 A (A &obj) 14 { 15 cout << "copy_constructor function called!" << endl; 16 } 17 ~A() 18 { 19 cout << "objext destory function called!" << endl; 20 } 21 void printf() 22 { 23 cout << this->a1 << " " << this->b1 << endl; 24 25 } 26 protected: 27 private: 28 int a1; 29 int b1; 30 }; 31 32 int main() 33 { 34 A(10, 10).printf(); 35 cout << "在此处打印之前,匿名对象就已经被析构!" << endl; 36 return 0; 37 }
3. 需要注意的点:
1. 所有形参都提供了默认的实参的构造函数也定义了默认构造函数,而这样的构造函数形参列表是有形参的(有参构造函数的形参有初始值的话,就相当于写了默认构造函数)
2. 匿名对象是否被析构看返回值是否有对象来接上
3. 拷贝构造函数的三种应用场景:
<1> a1 = a2 (区分两种不同的情况: A aa; A bb = aa;会 //bb = aa; 不会 ):一个对象初始化另一个对象时
<2> func(A a1):当对象作为函数参数时
<3> A a2 = func():当函数返回值为对象时(涉及到匿名对象的问题)
4. 特别注意:等号操作和对象的初始化是两个不同的概念