【C++】对象优化相关

目录

  • 对象使用过程中其背后调用了哪些方法
  • 函数调用过程中对象背后的调用方法

橙色

对象使用过程中其背后调用了哪些方法

t2和t3均调用了拷贝构造。值得看的是t4,构造t4的过程只调用了构造函数。这是C++编译器对于对象构造的优化:用临时对象(Test(20))生成新对象的时候,临时对象就不产生了,直接构造新对象就可以了

class Test
{
public:
    Test(int a=10):m(a)
    {
        cout << "Test()" << endl;
    }
    ~Test()
    {
        cout << "~Test()" << endl;
    }
    Test(const Test &t):m(t.m)
    {
        cout << "Test(const Test &)" << endl;
    }
      operator=(const Test &t)
    {
        cout << "operator=" << endl;
        m =t.m;
        return *this;
    }
private:
    int m;
};

int main() {
    Test t1;
    Test t2 = t1;
    Test t3 = t1;
    Test t4 = Test(20);//与Test t4(20);没有区别的
    cout << "----------" << endl;

    return 0;
}

【C++】对象优化相关_第1张图片

可以看到t2 = t1;这一行调用了赋值操作函数,t2 = Test(30);这一行先是调用了构造函数生成了临时对象,接着调用了赋值操作函数,最后是临时对象调用了析构函数。

int main() {
    Test t1;
    Test t2 = Test(20);
    cout << "----------" << endl;  
    t2 = t1;
    t2 = Test(30);
    cout << "----------" << endl;

    return 0;
}

【C++】对象优化相关_第2张图片

还有如下的两种方法,第一种用指针去指向一个临时对象是不可行的,因为临时对象的生存周期是该语句,执行到下一语句时就会被释放掉,此时p就成了一个野指针。而第二种则是引用,相当于给临时对象起了一个名字,此时这个临时对象的生命周期就变成了引用变量ref的生存周期

Test *p = &Test(40);
const Test &ref = Test(50);

【C++】对象优化相关_第3张图片

函数调用过程中对象背后的调用方法

分析一下这段代码,首先主函数中,t1和t2调用了构造函数;接着把t1传入函数的过程中,通过拷贝函数把t1 拷贝 给了形参t,为什么是拷贝而不是赋值呢?因为赋值是针对两个已经存在的函数对象,而形参t还未定义;接着temp调用了 构造函数 ,接着在return temp的过程中再次通过拷贝函数拷贝了一个临时对象,因为temp是函数中的一个临时变量,它的作用域仅限于函数体内;接着形参t和临时变量temp分别调用了析构函数;接着把临时对象赋值给t2,调用了赋值函数;接着临时对象、t2、t1依此调用了析构函数
【C++】对象优化相关_第4张图片
可以看到,上面这段短短的代码总共调用了11次函数,这样对内存的消耗无疑是巨大的。
该怎么改进呢?遵循以下三点:
1、函数参数传递过程中,对象优先按引用传递,不要按值传递。上面的形参改为引用类型,可以减掉形参的拷贝构造和形参的析构这两个函数调用。
通过第1步优化,这段代码仅需调用9个函数

2、函数返回对象的时候,应该优先返回一个临时对象,而不要返回一个定义过的对象。如下图这样,原本的流程是在Getobject函数中构造一个临时对象,但因为该临时对象无法走出Getobject函数作用域,所以要用该临时对象拷贝一个新对象返回。但前面已经学习过,当通过临时对象来拷贝一个新对象时,编译器会进行优化,不生成该临时对象,而是直接通过构造函数来构造新对象(该新对象是要返回给main函数中调用了该函数的,其生命周期仅限于main函数调用了该函数的那一语句)。因此就减少了Getobject函数中temp临时对象的构造和析构,又减少了两个函数的调用。
通过第2步优化,这段代码仅需调用7个函数

【C++】对象优化相关_第5张图片

3、接收返回值是对象的函数调用的时候,优先按初始化的方式接收,不要按赋值的方式接收。按如下的方式写,Getobject返回的是一个临时对象,又是通过临时对象拷贝构造一个新对象,所以该临时对象不生成,直接构造出一个新的对象
通过第3步,又减少了Getobjct(t1)这个临时对象的生成与析构,以及赋值函数的调用,共3个函数的调用,此时该段代码仅需调用4个函数即可
【C++】对象优化相关_第6张图片

你可能感兴趣的:(我的c++学习之路,c++,开发语言)