C++日记——Day18:临时对象探讨、解析

临时对象的概念

int i = 1;
int &&r1 = i++; //r1和i之间没有关系

另外一些临时对象,因为我们代码的书写问题而产生。统一称临时变量为临时对象。

 

产生临时对象的情况与解决

class TmpValue{
public:
    int val1;
    int val2;
public:
    TmpValue(int v1=0, int v2=0);
    TmpValue(const TmpValue &tmp);
    int Add(TmpValue tpobj);
    virtual ~TmpValue();
    TmpValue & operator=(const TmpValue &tmp);
};

TmpValue::TmpValue(int v1=0, int v2=0):val1(v1), val2(v2)
{
}

TmpValue::TmpValue(const TmpValue &tmp):val1(tmp.val1), val2(tmp.val2)
{
    cout << "调用了拷贝构造函数" << endl;
}

TmpValue::~TmpValue()
{
    cout << "调用了析构函数" << endl;
}

int TmpValue::Add(TmpValue tpobj)  //tpobj不属于真正的临时对象,真正的临时对象是 
                                   //临时生成且在代码中不可见的
{
    int Sum = tpobj.val1 + tpobj.val2;
    tpobj.val1 = 100;
    return Sum;
}

TmpValue & TmpValue::operator=(const TmpValue &tmp)
{
    val1 = tmp.val1;
    val2 = tmp.val2;
    return *this;
}


int main()
{
    TmpValue tp(12, 2);
    int sum = tp.Add(tp);
    cout << tp.val1 << endl;

    TmpValue tp2;
    tp2 = 100; //这里发生了隐式转换,产生了临时对象,调用了CTempValue的 
               //TmpValue(int v1, int v2)构造函数
               //tp2.val1的值赋值为100


}

类型转换生成临时对象,以保证函数调用成功

步骤:

1、用100这个数字创建了一个类型为TmpValue 的临时对象;

2、调用拷贝赋值运算符把这个临时对象里边的各个成员值赋给了sum 对象

3、销毁这个临时创建的对象TmpValue

 

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

int clac1(const string &str, char c){
    int cont = 0;
    //统计代码
    return cont;
}

int clac2(string &str, char c){
    int cont = 0;
    //统计代码
    return cont;
}

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

    int result = clac2(mystr, 'o');//C++判断你有修改string临时对象的可能,所以编译不通过
    
    return 0;
}

 

函数返回对象时

class TmpValue{
public:
    int val1;
    int val2;
public:
    TmpValue(int v1=0, int v2=0);
    TmpValue(const TmpValue &tmp);
    virtual ~TmpValue();
    TmpValue & operator=(const TmpValue &tmp);

};

TmpValue::TmpValue(int v1=0, int v2=0):val1(v1), val2(v2)
{
}

TmpValue::TmpValue(const TmpValue &tmp):val1(tmp.val1), val2(tmp.val2)
{
    cout << "调用了拷贝构造函数" << endl;
}

TmpValue::~TmpValue()
{
    cout << "调用了析构函数" << endl;
}

TmpValue & TmpValue::operator=(const TmpValue &tmp)
{
    val1 = tmp.val1;
    val2 = tmp.val2;
    return *this;
}

TmpValue Double(const TmpValue &tp)
{
    TmpValue tmp;
    tmp.val1 = tp.val1 * 2;
    tmp.val2 = tp.val2 * 2;
    return tmp;  //在这里因为tmp为临时对象,它的存在范围就是这个函数体中,出了函数 
                 //体就要被释放,为了让那个为了返回tmp,系统就会调用拷贝构造函数在 
                 //生成一个函数体外的临时对象作为返回值
}


int main()
{
    TmpValue tp(12, 2);
    Double(tp);

    TmpValue tp2 = Double(tp);  //return产生的临时对象被tp2接收,没有再调用拷贝构造函数初始化tp2
    TmpValue &&tp3 = Double(tp);//return产生的临时对象被tp3右值引用

}

因为返回临时对象,导致占用了一个拷贝构造函数和一个析构函数

Double()函数引起的消耗

TmpValue tmp;会消耗一个构造函数和析构函数

return tmp;会产生临时对象,占用一个拷贝构造函数和析构函数

优化:

TmpValue Double(const TmpValue &tp)
{
    return TmpValue(tp.val1 * 2, tp.val2 * 2); //这种方式会直接返回创建的对象,少创 
                                               //建了一个临时对象,节省了一个拷贝构 
                                               //造函数和析构函数
}

 

类外的运算符的重载

class myNum
{
    int num1;
    int num2;
};

myNum operator+(myNum &tmp1, myNum &tmp2)
{
    myNum result;
    result.num1 = tmp1.num1 + tmp2.num1;
    result.num2 = tmp1.num2 + tmp2.num2;
    return result;
}

int main(){
    myNum n1;
    n1.num1 = 10;
    n1.num2 = 100;

    myNum n2;
    n2.num1 = 10;
    n2.num2 = 100;

    myNum n3 = n1 + n2;
}

 

1、代码优化

2、需要经验

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值