匿名对象:临时的对象,一般都是在构造完就被释放掉了(有特殊情况,返回值优化)
1. 返回值优化:若是函数返回的匿名对象返回时候有同类型的新对象接上,则该匿名对象被转化为新对象。
#include "iostream" using namespace std; class A { public: A (int _a=0, int _b=0) { this->a1 = _a; this->b1 = _b; cout << "construct function called!" << endl; } A (A &obj) { cout << "copy_constructor function called!" << endl; } ~A() { cout << "objext destory function called!" << endl; } protected: private: int a1; int b1; }; // 函数返回值产生匿名对象 A g() { A a2(10,19); return a2; } // 测试一: 匿名对象用来初始化一个新对象。 void Test1() { A a1 = g(); } // 测试二: 用等号初始化一个新对象 void Test2() { A a3; a3 = g(); } int main() { Test1(); Test2(); return 0; }
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.没有对象名:普通情况,构造完成之后就直接被析构
#include "iostream" using namespace std; class A { public: A (int _a=0, int _b=0) { this->a1 = _a; this->b1 = _b; cout << "construct function called!" << endl; } A (A &obj) { cout << "copy_constructor function called!" << endl; } ~A() { cout << "objext destory function called!" << endl; } void printf() { cout << this->a1 << " " << this->b1 << endl; } protected: private: int a1; int b1; }; int main() { A(10, 10).printf(); cout << "在此处打印之前,匿名对象就已经被析构!" << endl; return 0; }
需要注意的点:
1. 所有形参都提供了默认的实参的构造函数也定义了默认构造函数,而这样的构造函数形参列表是有形参的(有参构造函数的形参有初始值的话,就相当于写了默认构造函数)
2. 匿名对象是否被析构看返回值是否有对象来接上
3. 拷贝构造函数的三种应用场景:
<1> a1 = a2 (区分两种不同的情况: A aa; A bb = aa;会 //bb = aa; 不会 ):一个对象初始化另一个对象时
<2> func(A a1):当对象作为函数参数时
<3> A a2 = func():当函数返回值为对象时(涉及到匿名对象的问题)
4. 特别注意:等号操作和对象的初始化是两个不同的概念