c++的多态有静态多态(编译时多态)和动态多态(运行时多态)。静态多态主要依靠函数重载、运算符重载和函数模板实现,在编译期间生成不同的函数与类型,由编译器根据函数签名或模板实例化选择正确函数与类型。多态多态主要依靠继承、虚函数与虚函数重写实现,在运行时选择执行哪个函数。
函数重载是指在同一作用域内,可以有一组相同函数名,不同参数列表的函数。重载函数通常用来命名一组功能相似的函数,这样可以减少函数名的数量,避免命名空间的污染。
void add(int i, int i); // 函数1
void add(float f, float f); // 函数2
int main()
{
add(1, 2); // 执行函数1
add(1.0f, 2.0f); // 执行函数2
return 0;
}
运算符重载是一种特殊的函数重载。c++类中有默认的运算符函数,重载运算符就是定义一个重载函数,当遇到该运算符时就使用此运算符重载函数来处理。
模板本身不是完整的代码,而是生成代码所用的蓝图。当使用具体类型实例化模板类或模板函数时,编译器会根据该类型生成特点版本的类或函数。
模板分为类模板和函数模板。依据模板生成不同的类或函数的过程,称之为模板的实例化,可化分为隐式实例化和显式实例化。 编译器为每个实例化的模板生成唯一的修饰名,避免命名冲突。
// 模板函数
template <typename T>
T add(T a, T b) {
return a + b; // 要求类型T支持+操作
}
int result = add(3, 5); // 隐式实例化,自动生成 add(int, int)函数
// 模板类
template <typename T>
class Box {
public:
void set(T t) { content = t; }
T get() { return content; }
private:
T content;
};
Box<std::string> stringBox; // 显式实例化,生成Box类,box.content的类型为string
在基类中可以使用virtual关键字声明虚函数,在子类中可以重写该虚函数。
class Base {
public:
// 定义虚函数
virtual int Get() {
return 1;
}
};
class Inherit : public Base {
public:
// 重写父类虚函数
virtual int Get() override {
return 2;
}
};
int main() {
Base* base = new Base();
Inherit inherit = new Inherit();
base.Get(); // 返回1,调用Base类的Get()函数
inherit.Get(); // 返回2,调用Inherit类的Get()函数
return 0;
}
class A { int a; virtual void func(); };
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {}; // D继承B、C,存放B、C的虚基表,通过虚基表访问共享基类成员
/*
/ D对象中:
/ B类虚函数表指针
/ B类虚基表指针 // 由此到A类成员
/ [B类成员]
/
/ C类虚函数表指针
/ C类虚基表指针 // 由此到A类成员
/ [C类成员]
/
/ [D类成员]
/
/ [唯一共享的A类成员]
*/
正春华枝俏,待秋实果茂,愿与君共勉