美文网首页PyQt
聪明的编译器

聪明的编译器

作者: 223480235e8e | 来源:发表于2019-01-27 11:04 被阅读15次

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

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

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

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

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

    例如:

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

    那么,编译器就会分析实例c是MyClass类型,只有一个参数,且25为整数类型,所以c.fun(25)被编译之后,其函数名可能变为MyClass_fun_int,那么编译器就可以根据这个唯一的名字找到我这个接口的入口地址,从而执行该入口地址所对应的代码段。

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

    • 参数个数不同,可以重载

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

    • const参数可以重载,可以把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++可以忽略接口的返回值,所以如果只用返回值来作为重载条件是不够的,也是不可取的。所以编译器会在这里报重定义的错误。

    最后也希望大家多多支持小豆君的创作,关注小豆君的公众号“小豆君Qt分享”,最新文章都会在公众号第一时间发布,或者你有不懂的问题,关注公众号后,可加好友或进Qt群获得答案。

    相关文章

      网友评论

        本文标题:聪明的编译器

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