博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C/CPP-临时对象

Posted on 2023-03-13 09:34  乔55  阅读(27)  评论(0编辑  收藏  举报

临时对象详解

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);临时对象不立即析构。可看出,临时对象是一种右值