静态联编和动态联编
静态联编指的是联编工作出现在写代码阶段,又称之为早期联编或静态约束。在编译期确定要调用的函数,之前写的都是静态联编的。
动态联编指的是指的是编译阶段不能确定将要调用的函数,只能在程序运行的时候才能确定将要调用的函数,也就是说在程序运行的时候才将函数实现和函数调用关联。也叫晚期联编,或动态约束。运行时才确定函数的地址。
#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();
}虚函数
虚函数的特性:
- 如果类中出现了虚函数表,类的头部会插入一个指向虚函数的指针
- 如果父类是虚函数,那么子类重写的函数也是虚函数
- 类中多出了一个指针指向一个虚函数表,虚函数表里存虚函数的首地址,调用虚函数时先查表在调用
- 虚函数表不会被继承,但表中的项会继承
虚函数的使用:
- 父类中的虚函数子类一般会继承重写实现自己的功能
- 父类指针或引用调用哪个子类虚函数成员,那么调用的就是那个子类的虚函数成员
- 父类要用虚析构函数子类才能调用自己重写的虚析构函数,不然只能调到父类的析构函数造成内存泄露
纯虚函数:virtual void fun() = 0;
抽象类:只含有纯虚函数,自身不能实例化(就是说不能创建类对象,但可以通过子类继承重写虚函数,然后创建子类的对象)。其可以当做一种规范来使用,如果子类不重写它的虚函数那么子类也不能创建类对象
final:
修饰类代表它是最后一代,没有子类了,别人继承不了它
class B final : public class A {}
修饰虚函数代表后面的子类重写不了这个虚函数了,比如 A 纯虚函数,B 继承 A 重写,C 继承 B 但我不希望重写那就 void fun() final {}