关于多态的疑惑解决思路
关于多态的疑惑
//基类
class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
};
//子类
class Case : public Base
{
public:
void f() { cout << "Case::f1" << endl; }
};
int main()
{
Base *B = new Case;
B->f();
}
各位大牛 主函数里的第一句是用子类去实例化一个基类对象,他为什么就掉用了 Case::f1,而不是Base::f1呢??
就算是找虚拟表 这个类型毕竟是Base类型的 他的f()函数也是虚的 为什么查找虚拟表的时候没找到自己的 而找到了子类的呢?? 晚生愚钝 希望大侠们不吝解惑啊!
------解决方案--------------------
因为不同对象vptr所指的vtable不同。Case对象的vptr自然就指向Case类的vtable
------解决方案--------------------
指针和引用,会调用实际类型的方法
------解决方案--------------------
实际上基类与子类只有一套虚函数表(vtable),而基类与继承类都有一个虚函数指针vptr指向虚函数表,虚函数表中存放的是虚函数的地址(可以看成通过此处访问确定的函数),当基类virtual限定的时候,将其函数地址放在虚函数表中,而子类如果含有与其父类相同的虚函数则覆盖!这也就是为什么可以通过基类指针访问继承类方法的原因了,说了这么多不知道有没有说清楚!
------解决方案--------------------
如果找的是Base::f1就没有多态了,多态的好处之一是运行时绑定对象,在扩展程序时会得到好处,
虚函数也是接口的基础,接口是COM和插件机制的基础。运行时绑定就是说定义一个公共的基类
存放一份虚函数表,然后所有使用者调用这个公共的基类里面的方法,当运行时绑定到继承类时,
调用基类的代码实际上调用了继承类,如此实现了扩展。当有新的继承类时,无需修改调用代码。
所以,这个机制很重要。
//基类
class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
};
//子类
class Case : public Base
{
public:
void f() { cout << "Case::f1" << endl; }
};
int main()
{
Base *B = new Case;
B->f();
}
各位大牛 主函数里的第一句是用子类去实例化一个基类对象,他为什么就掉用了 Case::f1,而不是Base::f1呢??
就算是找虚拟表 这个类型毕竟是Base类型的 他的f()函数也是虚的 为什么查找虚拟表的时候没找到自己的 而找到了子类的呢?? 晚生愚钝 希望大侠们不吝解惑啊!
------解决方案--------------------
因为不同对象vptr所指的vtable不同。Case对象的vptr自然就指向Case类的vtable
------解决方案--------------------
指针和引用,会调用实际类型的方法
------解决方案--------------------
实际上基类与子类只有一套虚函数表(vtable),而基类与继承类都有一个虚函数指针vptr指向虚函数表,虚函数表中存放的是虚函数的地址(可以看成通过此处访问确定的函数),当基类virtual限定的时候,将其函数地址放在虚函数表中,而子类如果含有与其父类相同的虚函数则覆盖!这也就是为什么可以通过基类指针访问继承类方法的原因了,说了这么多不知道有没有说清楚!
------解决方案--------------------
如果找的是Base::f1就没有多态了,多态的好处之一是运行时绑定对象,在扩展程序时会得到好处,
虚函数也是接口的基础,接口是COM和插件机制的基础。运行时绑定就是说定义一个公共的基类
存放一份虚函数表,然后所有使用者调用这个公共的基类里面的方法,当运行时绑定到继承类时,
调用基类的代码实际上调用了继承类,如此实现了扩展。当有新的继承类时,无需修改调用代码。
所以,这个机制很重要。