临时对象详解
class Test
{
public:
int a;
int b;
Test(int a1 = 0, int b1 = 0) :a(a1), b(b1)
{
cout << "普通构造" << endl;
}
Test(const Test& t) :a(t.a), b(t.b)
{
cout << "拷贝构造" << endl;
}
virtual ~Test()
{
cout << "析构函数" << endl;
}
int add(Test t)
{
int tmp = t.a + t.b;
t.a = 10;
return tmp;
}
};
// 场景1:以传值的方式给函数传递参数
// 将add的形参改为引用方式,就不会产生拷贝构造操作,提高效率
// 调用拷贝构造,将类对象t传递给add,产生临时对象temp接收实参t
void test1()
{
Test t(10, 20);
int sum = t.add(t);
}
// 场景2:用对象给已创建对象赋值时,2者参数不一致,会产生临时对象
void test2()
{
// 1、会产生临时对象
// 调用普通构造函数,产生临时对象temp(50,0),temp赋值给t
Test t;
t = 50;
// 2、不产生临时对象
// t可直接接收t1,不需要通过临时对象来传递
Test t1(20,30);
t=t1;
}
// 场景3:隐式类型转换,因类型不一致,产生临时对象,以保证函数调用成功
// C++只会对const引用产生临时对象,非const引用不会产生临时对象
// 因为,若不加const时,系统认为你有修改临时对象temp的倾向
// 因此,不会对非const引用产生临时对象,否则,临时变量可能被修改
int calc(const string src,char ch)
{ // 计算字符ch在src中出现的次数
const char* p = src.c_str();
int count = 0;
//...省略具体的实现功能
return count;
}
// 调用clac函数时,产生临时对象来接收裸实参str,再将temp传入clas
void test3()
{
char str[100]="i love you";
int ret = calc(str,'y');
}
// 场景4:函数返回类对象时会产生临时对象
Test Test::double(Test& t)
{
Test tx;
tx.a = t.a * 2;
tx.b = t.b * 2;
return tx; // 产生临时对象返回
return Test(t.a*2,t.b*2);
// 优化代码。只调用了普通构造函数,不调用拷贝构造函数生成临时对象
}
// 调用:Double(t); 只要出了函数Double,临时对象立即析构
// 调用:Test t1=Double(t);临时对象不会立即析构,t1就代表了临时对象
// 调用:Test&& t2=Double(t);临时对象不立即析构。可看出,临时对象是一种右值