美文网首页互联网@时事传播c/c++
C++类---临时对象深入探讨、解析,提高性能手段

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

作者: CPlusPlus图像处理 | 来源:发表于2019-04-06 02:01 被阅读4次

    一、临时对象的概念

        // 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;
    

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/keeliqtx.html