过程描述

我们的代码在变成可执行文件之前,会经历两步优化。编译器优化和代码优化。

我们以g++编译为例看下面编译器优化的例子:

#include <iostream>
using namespace std;

class HasPtrMen {
public:
    int *d;
    static int n_cstr;
    static int n_dstr;
    static int n_cptr;
    HasPtrMen(): d(new int(0)) {
        cout << "constructor: " << ++n_cstr << endl;
    }
    HasPtrMen(const HasPtrMen &h) : d(new int(*h.d)) {
        cout << "copy constructor: " << ++n_cptr << endl;
    }
    ~HasPtrMen() {
        cout << "destructor: " << ++n_dstr << endl;
    }
};
int HasPtrMen::n_cstr = 0;
int HasPtrMen::n_dstr = 0;
int HasPtrMen::n_cptr = 0;
HasPtrMen GetTemp() { return HasPtrMen(); }

int main() {
    HasPtrMen a = GetTemp();
    return 0;
}

g++正常编译后输出结果如下:
在这里插入图片描述

这和我们所学知识是矛盾的!不应该如此,我自己还没有给该引用的地方加引用呢!

我们试试不优化后输出结果是什么:

图片

对!它如下所示,中间详细的过程如下:

  1. 在调用GetTemp()时,HasPtrMen()被创建调用了构造函数(第一行输出)

  2. return时调用了拷贝构造,然后销毁,调用析构函数(第二三行输出)

  3. 来到外部看到=后将return的结果再次赋值给变量a,调用拷贝构造(第四行输出)

  4. return结果销毁,调用析构函数(第五行输出)

  5. 最后main函数结束,a对象销毁,调用析构函数(第六行输出)

结论

此时如果我们给GetTemp()的return结果加引用或进行其他优化,都基本收效甚微,因为在编译过程中,编译器已经给我们优化过了!

具体的优化逻辑和算法,我们不做讨论,只是我们需要知道有这样一个优化过程!除了编译器优化,文章开头还提到了代码优化,这里多说两句,我们知道C++代码编译分为预处理、编译、汇编、链接四个步骤!其中编译大体指的就是编译原理的内容,大概分为词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成这几步,代码优化就是在这个时候进行的,它是在编译过程中对生成的平台无关的中间代码进行通用优化的一个过程!

觉得文章不错,记得点赞、收藏,有任何问题欢迎评论探讨。