【C++】对象优化的三条原则

1、函数参数传递过程中,对象优先按引用传递,不要按值传递

按值传递形参会调用拷贝构造拷贝实参

#include <iostream>
using namespace std;

class Test{
public:
    Test(int data = 10) :ma(data){
        cout<<"Test(int)"<<endl;
    }
    ~Test(){
        cout << "~Test()" << endl;
    }
    Test(const Test &t):ma(t.ma){
        cout<<"Test(const Test &t)"<<endl;
    }
    Test& operator=(const Test &t){
        ma = t.ma;
        cout<<"Test& operator=(const Test &t)"<<endl;
    }
    int getData() const{
        return ma;
    }
private:
    int ma;
};

/*
 * 1.函数参数传递过程中,对象优先按引用传递,不要按值传递
 * java底层好像也是这么使用指针实现的
 * 2.函数返回对象的时候,优先返回一个临时对象,而不要返回一个定义过的对象(这一步可以忽略,现在的编译器就算定义过的局部对象也会直接构造在上级栈帧上)
 */
Test GetObject(Test &t){
    int val = t.getData();

    Test tmp(val);
    return tmp;
}

int main(){
    Test t1; // 1.Test(int data = 10)
    Test t2; // 2.Test(int data = 10)
    // t2 = GetObject(t1); // 4.拷贝构造main函数栈帧的临时对象
    // 5.~Test() 函数返回值临时对象析构
    // 6.~Test() t1
    // 7.~Test() t2
    return 0;
}

2、函数返回对象的时候,优先返回一个临时对象,而不要返回一个定义过的对象(这一步可以忽略,现在的编译器就算定义过的返回值对象也会直接构造在上级栈帧上)

#include <iostream>
using namespace std;

class Test{
public:
    Test(int data = 10) :ma(data){
        cout<<"Test(int)"<<endl;
    }
    ~Test(){
        cout << "~Test()" << endl;
    }
    Test(const Test &t):ma(t.ma){
        cout<<"Test(const Test &t)"<<endl;
    }
    Test& operator=(const Test &t){
        ma = t.ma;
        cout<<"Test& operator=(const Test &t)"<<endl;
    }
    int getData() const{
        return ma;
    }
private:
    int ma;
};

/*
 * 1.函数参数传递过程中,对象优先按引用传递,不要按值传递
 * java底层好像也是这么使用指针实现的
 * 2.函数返回对象的时候,优先返回一个临时对象,而不要返回一个定义过的对象(这一步可以忽略,现在的编译器就算定义过的对象也会直接构造在上级栈帧上)
 */
Test GetObject(Test &t){
    int val = t.getData();

    // Test tmp(val);
    // return tmp;

    // 返回临时对象
    return Test(val); // 2.返回值对象优化构造在上级函数栈帧上
}

int main(){
    Test t1; // 1.Test(int data = 10)
    Test t2 = GetObject(t1); // 使用右值临时对像构造新对象,新对象直接被临时对象构造
    // t2 = GetObject(t1);
    // 3. ~Test()
    // 4. ~Test()

    return 0;
}

3、接受返回值对象是函数调用的时候,优先按照初始化接受,不要按照赋值方式接受

这样返回值临时对象直接被命名为新对象,而不会先构造新对象再赋值重载函数接受

#include <iostream>
using namespace std;

class Test{
public:
    Test(int data = 10) :ma(data){
        cout<<"Test(int)"<<endl;
    }
    ~Test(){
        cout << "~Test()" << endl;
    }
    Test(const Test &t):ma(t.ma){
        cout<<"Test(const Test &t)"<<endl;
    }
    Test& operator=(const Test &t){
        ma = t.ma;
        cout<<"Test& operator=(const Test &t)"<<endl;
    }
    int getData() const{
        return ma;
    }
private:
    int ma;
};

/*
 * 1.函数参数传递过程中,对象优先按引用传递,不要按值传递
 * java底层好像也是这么使用指针实现的
 * 2.函数返回对象的时候,优先返回一个临时对象,而不要返回一个定义过的对象(这一步可以忽略,现在的编译器就算定义过的对象也会直接构造在上级栈帧上)
 * 3.接受返回值对象是函数调用的时候,优先按照初始化接受,不要按照赋值方式接受
 */
Test GetObject(Test &t){
    int val = t.getData();

    // Test tmp(val);
    // return tmp;

    // 返回临时对象
    return Test(val); // 2.返回值对象优化构造在上级函数栈帧上
}

int main(){
    Test t1; // 1.Test(int data = 10)
    Test t2 = GetObject(t1); // 使用右值临时对像构造新对象,新对象直接被临时对象构造
    // t2 = GetObject(t1);
    // 3. ~Test()
    // 4. ~Test()

    return 0;
}
posted @ 2025-04-27 22:25  丘狸尾  阅读(6)  评论(0)    收藏  举报