C++类---临时对象深入探讨、解析,提高性能手段

一、临时对象的概念

    // i++,++i
    int i = 1;
    int &&r1 = i++;  // 右值引用  r1和i之间没有什么关系
    r1 = 19;
    i = 80;
    // 另外一些临时对象,是因为我们代码书写问题而产生的,统一称临时变量为临时对象
    // new(堆) delete(释放new的对象) 栈(临时对象)

二、产生临时对象的情况和解决:三种情况和解决方案

CTempValue类的结构

class CTempValue 
{
public:
    int val1;
    int val2;
public:
    CTempValue(int v1 = 0, int v2 = 0);
    CTempValue(const CTempValue &t) :val1(t.val1), val2(t.val2)  // 拷贝构造函数
    {
        cout << "copy construct" << endl;
    }
    virtual ~CTempValue() // 析构函数
    {
        cout << "destructor" << endl;
    }
      
    CTempValue& operator=(const CTempValue &tmp)    // 拷贝复制运算符
    {
        val1 = tmp.val1;
        val2 = tmp.val2;
        cout << "Copy replication operator " << endl;
        return *this;
    }
public:
    int Add(CTempValue tObj);  // 普通函数
    int Add1(CTempValue &tObj);
};

2.1以传值的方式给函数传递参数

int CTempValue::Add(CTempValue tObj) // 拷贝构造函数在tObj这个临时对象发生
{
    int tmp = tObj.val1 + tObj.val2;
    tObj.val1 = 1000;  // 对外界的之没有影响
    return tmp;  // 会调用析构函数
}
// main函数调用
CTempValue tm(10, 20);  // 调用了构造函数
int Sum = tm.Add(tm);   // 调用了拷贝构造函数
cout << "Sum = " << Sum << endl;
cout << "tm.val1 = " << tm.val1 << endl;

生成的结果-影响系统的性能

生成的结果-影响系统的性能

int CTempValue::Add1(CTempValue &tObj)
{
    int tmp = tObj.val1 + tObj.val2;
    tObj.val1 = 1000;  // 会修改val1的值
    return tmp;
}

// main函数调用
CTempValue tm(10, 20);  // 调用了构造函数
int Sum = tm.Add(tm);   
cout << "Sum = " << Sum << endl;
cout << "tm.val1 = " << tm.val1 << endl;

生成的结果---未调用拷贝构造函数与析构函数>>提高系统的性能

生成的结果---未调用拷贝构造函数与析构函数>>提高系统的性能

2.2类型转换生成的临时对象/隐士类型转换以保证函数调用成功

类型转换生成的临时对象

CTempValue sumx;
sumx = 1000;  // 产生了真正的临时对象

生成的结果---调用了拷贝赋值运算符

生成的结果---调用了拷贝赋值运算符

 

(1)用1000这个数字创建一个类型为CTempValue的临时对象
(2)调用拷贝赋值运算符把这个临时对象里面的成员值赋给了sumx对象
(3)销毁这个临时对象创建的CTempValue对象

// 把定义对象和给对象初值放在一行上
// 用1000构造sumx对象,而且是直接构造在sumx对象预留空间里
CTempValue sumx = 1000; // 只调用了一次构造函数

生成的结果---只调用了一次构造函数

生成的结果---只调用了一次构造函数

隐士类型转换以保证函数调用成功

// 统计字符ch在字符串strsource里出现的次数,把次数返回回去
int calcCount(const string &strsource, char ch)// strsource这个形参绑定到了string这个临时对象
{// 若不加const 则认为会修改strsource这个临时对象 
    const char *p = strsource.c_str();
    int icount = 0;
    // ......
    return icount;
}

// main函数调用
char mystr[100] = "I love china!oh yeah!";
int result = calcCount(mystr,'o'); // char[] --> string 会产生临时对象
//C++语言只会为const引用(const string &strsource)产生临时变量,而不会为非const引用产生临时变量

string mystr1 = "I love china!oh yeah!";
result = calcCount(mystr, 'o'); // 这样加const与不加const时一样的,因为不需要产生临时对象

2.3函数返回对象的时候

CTempValue Double(CTempValue &ts) // 形参未消耗,返回值会消耗
{
    CTempValue tmp;  // 消耗一个构造函数与析构函数
    tmp.val1 = ts.val1 * 2;
    tmp.val2 = ts.val2 * 2;
    return tmp; 
}
// main函数调用
CTempValue ts(10, 20);  // 拷贝
// 因为返回临时对象导致占用了一个拷贝构造函数和一个析构函数
Double(ts);  // 未接收返回的变量--->释放+析构函数

生成的结果---消耗性能

生成的结果---消耗性能

CTempValue Double(CTempValue &ts) // 形参未消耗,返回值会消耗
{
    CTempValue tmp;  // 消耗一个构造函数与析构函数
    tmp.val1 = ts.val1 * 2;
    tmp.val2 = ts.val2 * 2;
    return tmp; //产生临时对象,占用一个拷贝构造函数与析构函数
}

// main函数调用
CTempValue ts(10, 20);  // 拷贝
// 因为返回临时对象导致占用了一个拷贝构造函数和一个析构函数
CTempValue tx = Double(ts);  // 返回对象接收

生成的结果---少一个析构函数

生成的结果---少一个析构函数

 

Double()函数引起的消耗:
CTempValue tmp:会消耗一个构造函数与析构函数
return tmp:产生临时对象,占用一个拷贝构造函数与析构函数

CTempValue ts(10, 20);
CTempValue tx =  Double(ts);

生成的结果 --- 低消耗

生成的结果 --- 低消耗

类外运算符重载

class mynum
{
public:
    int num1;
    int num2;
public:
    mynum(int num11 = 0, int num21 = 0) : num1(num11), num2(num21) {}
};

mynum operator+(mynum &tmpnum1, mynum &tmpnum2)
{
    return mynum(tmpnum1.num1 + tmpnum2.num1, tmpnum1.num2 + tmpnum2.num2);
}

// main函数调用
mynum tmp;
tmp.num1 = 10;
tmp.num2 = 100;

mynum tmp2;
tmp2.num1 = 20;
tmp2.num2 = 200;

mynum tmp3 = tmp + tmp2;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值