静态联编和动态联编

静态联编指的是联编工作出现在写代码阶段,又称之为早期联编或静态约束。在编译期确定要调用的函数,之前写的都是静态联编的。

动态联编指的是指的是编译阶段不能确定将要调用的函数,只能在程序运行的时候才能确定将要调用的函数,也就是说在程序运行的时候才将函数实现和函数调用关联。也叫晚期联编,或动态约束。运行时才确定函数的地址。

#include <iostream>
 
void show1 () {
    std::cout << "调用show1";
}
 
void show2 () {
    std::cout << "调用show2";
}
 
int main () {
    void (*pShow)(); //定义函数指针
    pShow = show1;   //让函数指针指向show1函数
    pShow();         //通过函数指针调用show1函数
 
    pShow = show2;   //让函数指针指向show2函数
    pShow();         //通过函数指针调用show2函数   
}

多态

也就是同一个接口,通过不同的对象调用就有不同的效果

多态的实现:只需要在类中的函数成员前面加一个 virtual 关键字即可

静态多态:函数重载

int add (int a,int b) {
	return a+b;
}
double add (double a,double b) {
	return a+b;
}

动态多态:虚函数 (虚函数可以被子类重写)

class roastDuck {
    public:
    virtual void show() {
        std::cout << "烤鸭\n";
    }
};
 
class peKingRoastDuck : public roastDuck {
    public:
    void show() {
        std::cout << "北京烤鸭\n";
    }
};
 
class nanJingRoastDuck : public roastDuck {
    public:
    void show() {
        std::cout << "南京烤鸭\n";
    }
};
 
int main () {
    roastDuck* a = new peKingRoastDuck();
    a->show();
    roastDuck* b = new nanJingRoastDuck();
    b->show();
}

虚函数

虚函数的特性:

  1. 如果类中出现了虚函数表,类的头部会插入一个指向虚函数的指针
  2. 如果父类是虚函数,那么子类重写的函数也是虚函数
  3. 类中多出了一个指针指向一个虚函数表,虚函数表里存虚函数的首地址,调用虚函数时先查表在调用
  4. 虚函数表不会被继承,但表中的项会继承

虚函数的使用:

  1. 父类中的虚函数子类一般会继承重写实现自己的功能
  2. 父类指针或引用调用哪个子类虚函数成员,那么调用的就是那个子类的虚函数成员
  3. 父类要用虚析构函数子类才能调用自己重写的虚析构函数,不然只能调到父类的析构函数造成内存泄露

纯虚函数:virtual void fun() = 0;

抽象类:只含有纯虚函数,自身不能实例化(就是说不能创建类对象,但可以通过子类继承重写虚函数,然后创建子类的对象)。其可以当做一种规范来使用,如果子类不重写它的虚函数那么子类也不能创建类对象

final:
修饰类代表它是最后一代,没有子类了,别人继承不了它
class B final : public class A {}
修饰虚函数代表后面的子类重写不了这个虚函数了,比如 A 纯虚函数,B 继承 A 重写,C 继承 B 但我不希望重写那就 void fun() final {}