一、多态的概念
1.1 编译时多态
编译时多态主要是函数重载和函数模板,它们实现多态主要是通过传不同类型的参数。之所以称为编译时多态,是因为参数的匹配是发生在编译阶段的,这种也被称为静态绑定。
1.2 运行时多态
运行时多态可以认为是通过对象来区分行为的,而编译时多态是通过类型的。就好像同样是'叫'这个行为,传猫过去就是'喵喵',传狗过去就是'汪汪'。
二、多态的定义和使用
2.1 多态的判定标准
- 要是用基类的引用或者指针来调用;
- 被调用的函数是虚函数;
- 调用函数需要构成重写。
我们这里着重讲一下为什么一定要用基类的指针或者是引用调用:
因为多态的内核就是'在运行时确定'。假如使用的是基类的对象,那么在编译的时候对象的类型就是明确的基类类型,这时候就起不到运行时确定的效果了。假设是使用指针或者是引用来调用,在运行时是不知道具体指向的类型的,这时候就需要去查找虚函数表,就可以实现'运行时确认'。
2.1.1 虚函数
在函数声明之前加上 virtual 关键字,这个函数就是虚函数。
virtual void func()
2.1.2 函数重写
函数重写需要构成以下条件:
- 两个函数的函数名、参数、返回值全部相等;
- 两个函数全都是虚函数。
补充:派生类中的函数不是虚函数也是可以的,但是基类中的函数一定是虚函数,此时相当于是将基类中函数的 virtual 关键字继承下来了,此时重写后的函数相当于是将基类的函数名和参数和派生类的函数实现拼在一起了。
2.2 相关的题目
以下程序输出结果是什么? A: A->0 B: B->1 C: A->1 D: B->0 E: 编译出错 F: 以上都不正确
class A {
public:
virtual void func(int val = 1) {
std::cout << "A->" << val << std::endl;
}
virtual void test() {
func();
}
};
class B : public A {
public:
void func {
std::cout << << val << std::endl;
}
};
{
B* p = B;
p->();
;
}


