从名字上就可以看出
动态绑定:即需要编译器动态的处理:需要用到的时候再编译,需要编译的时候才已知
静态调用:编译前必须定义
动态绑定需要的条件:
1.以指针形式
2.用的必须是虚函数
3.必须是向上转型:(通俗的来讲就是基类指针指向->派生类对象)
前两点很好理解
主要是第三点
首先我们需要知道的就是子类拥有基类的“一切”--------非私有
那么基类可以是派生类的一部分,也可以不是,所以基类不可以隐式转换为派生类,但是可以通过基类的指针来使用派生类对象中的基类部分。
动态绑定更多用来实现多态,以及更好的用容器来存储,因为每个派生类都是不同的,所以不能用容器来保存每个派生类对象,但是我们可以用容器来保存指向这些对象的指针。
还有要注意的是:派生类重写基类的虚函数时,必须参数一致,如果不一致,那么基类指针就无法使用派生类对象所重写的虚函数
原因:类的作用域不一致,当派生类内定义一个与基类名字一致的函数时,会直接隐藏基类中同名的函数,所以如果讲基类的虚函数重写时参数列表不一致,那么相当于隐藏掉继承下来的虚函数,且创造了一个新的独属于派生类的成员函数,此时基类指针就会从基类出发,开始找到能调用的最后一个虚函数
举例:
class A {
public:
virtual void f() { cout << "1" << endl; }
};
class B: public A {
void f() { cout << "2" << endl; }
void f(int) { cout << "3" << endl; }
};
class C : public B {
//void f() { cout << "4" << endl; } //这里我注释掉了
void f(int) { cout << "5" << endl; } //隐藏了基类的虚函数f()
};
int main()
{
C c;
A* bp1 = &c;
bp1->f(); //这里输出2基类A往下找派生类B中有虚函数且参数列表一致,但是找不到C中的虚函数
bp1->f(5); //直接报错,因为A中根本没有满足这个参数表的f()
return 0;
}