C++临时匿名对象

匿名对象:临时的对象,一般都是在构造完就被释放掉了(有特殊情况,返回值优化)

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 }
View Code
// 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 }
View Code

 

3. 需要注意的点:

  1. 所有形参都提供了默认的实参的构造函数也定义了默认构造函数,而这样的构造函数形参列表是有形参的(有参构造函数的形参有初始值的话,就相当于写了默认构造函数)

  2. 匿名对象是否被析构看返回值是否有对象来接上

  3. 拷贝构造函数的三种应用场景:
     <1> a1 = a2 (区分两种不同的情况: A aa; A bb = aa;会 //bb = aa; 不会   ):一个对象初始化另一个对象时
     <2> func(A a1):当对象作为函数参数时
     <3> A a2 = func():当函数返回值为对象时(涉及到匿名对象的问题) 

4. 特别注意:等号操作和对象的初始化是两个不同的概念

posted @ 2015-07-01 12:33  ariclee  阅读(1660)  评论(0编辑  收藏  举报