聪明的编译器

Posted 小豆君Qt分享

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聪明的编译器相关的知识,希望对你有一定的参考价值。

前一阵,一位朋友问我,编译器是如何知道当传入不同参数就会调用同一个类中的同名函数,我想,这也许是很多初学者经常遇到的问题,今天小豆君就来说说这个原理。


在讲原理之前,我先来讲一个生活中的例子——取名字。


好听好记的汉字就那么多,很多家长在给孩子起名字时难免“撞衫”。比如,我高中一班的一个同学叫“刘洋”,二班的同学也有个叫“刘洋”,那么我们为了区分这两个人,就可能会给她们重命名为“一班刘洋”,“二班刘洋”,这样就可以准确区分啦。


而在编程中,好用简单的英文也就是那么多个,况且我英文水平也不高,一堆程序员在一起编程,难免会起重名字。


讲到这里,我想聪明的小伙伴们就发现了,其实,在我们程序中编译器就是将所有的类名,函数名,参数类型,名字空间等等拼接起来,从而为每个函数生成了一个唯一的名字。


例如:

class MyClass
{
public:
    int fun();
    int fun(int param1);
    int fun(const int& param1);
    int fun(double param1);
    int fun(double param1, const string& param2);
    int fun() const;
};


上面的这段代码定义了5个同名参数,那么这些函数接口在编译器中的名字可能分别为


class MyClass
{
public:
    //注释为对应编译器重新生成的名字
    int fun();//=>MyClass_fun
    int fun(int param1);//=>MyClass_fun_int
    int fun(const int& param1);//=>MyClass_fun_const_int
    int fun(double param1);//=>MyClass_fun_double
    int fun(double param1, const string& param2);//=>MyClass_fun_double_string
    int fun() const;//=>MyClass_fun_const
};


当我在程序中写

MyClass c;
c.fun(25);



所以,你就不难理解下面的重载条件:

  1. 参数个数不同,可以重载

  2. 参数个数相同,但参数类型不同也可重载

  3. const参数可以重载,可以把const修饰的对象和普通对象看作是两种类型

  4. const函数可以重载


我们还知道,返回值是不能作为重载条件的,请看下面代码

比如我在MyClass类中又定义了一个返回string类型的fun接口

string fun();


那么请看下面的代码,编译器该如何翻译

MyClass c;//假设返回值可以作为重载条件
int val1 = c.fun();//重命名为 int_MyClass_fun
string val2 = c.fun();//重命名为string_MyClass_fun
c.fun();//这个该如何重命名呢?int_MyClass_fun还是string_MyClass_fun?


从上面的示例中,我们可以看出,正因为C++可以忽略接口的返回值,所以如果只用返回值来作为重载条件是不够的,也是不可取的。所以编译器会在这里报重定义的错误。


好了,关于C++的静态重载就先给大家分享到这里了,我们下期再见。

以上是关于聪明的编译器的主要内容,如果未能解决你的问题,请参考以下文章

是否可以动态编译和执行 C# 代码片段?

c# 8 switch 表达式不够“聪明”

Notepad++编辑器——Verilog代码片段直接编译

如何有条件地将 C 代码片段编译到我的 Perl 模块?

导致资产预编译在heroku部署上失败的代码片段

iOS代码片段CodeSnippets