C/C++你必须知道的小知识(14)

185 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

1.3.4 说说 C++ 的重载和重写是如何实现的

参考答案

  1. C++利用命名倾轧(name mangling)技术,来改名函数名,区分参数不同的同名函数。命名倾轧是在编译阶段完成的。

    C++定义同名重载函数:

    #include<iostream>
    using namespace std;
    int func(int a,double b)
    {
        return ((a)+(b));
    }
    int func(double a,float b)
    {
        return ((a)+(b));
    }
    int func(float a,int b)
    {
        return ((a)+(b));
    }
    int main()
    {
        return 0;
    }
    

    由上图可得,d代表double,f代表float,i代表int,加上参数首字母以区分同名函数。

  2. 在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。

    1. 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。
    2. 存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。
    3. 多态性是一个接口多种实现,是面向对象的核心,分为类的多态性和函数的多态性。
    4. 重写用虚函数来实现,结合动态绑定。
    5. 纯虚函数是虚函数再加上 = 0。
    6. 抽象类是指包括至少一个纯虚函数的类。

    纯虚函数:virtual void fun()=0。即抽象类必须在子类实现这个函数,即先有名称,没有内容,在派生类实现内容。

1.3.5 说说 C 语言如何实现 C++ 语言中的重载

参考答案

c语言中不允许有同名函数,因为编译时函数命名是一样的,不像c++会添加参数类型和返回类型作为函数编译后的名称,进而实现重载。如果要用c语言显现函数重载,可通过以下方式来实现:

  1. 使用函数指针来实现,重载的函数不能使用同名称,只是类似的实现了函数重载功能
  2. 重载函数使用可变参数,方式如打开文件open函数
  3. gcc有内置函数,程序使用编译函数可以实现函数重载

示例如下:

#include<stdio.h>

void func_int(void * a)
{
    printf("%d\n",*(int*)a);  //输出int类型,注意 void * 转化为int
}

void func_double(void * b)
{
    printf("%.2f\n",*(double*)b);
}

typedef void (*ptr)(void *);  //typedef申明一个函数指针

void c_func(ptr p,void *param)
{
     p(param);                //调用对应函数
}

int main()
{
    int a = 23;
    double b = 23.23;
    c_func(func_int,&a);
    c_func(func_double,&b);
    return 0;
}