C++也学了一段时间了,C++比较让人混乱的除了复杂的标准库和算法.基础部分里大概应该属指针 引用和函数传参的问题了,对于这些头疼的问题,我们只能多看 多写,多练,没有更好的办法.
C++的多态性就和这些因素有所关系.今天我来说说自己所掌握的关于多态的知识!
我假设现在的你已经了解C++基于对象的部分,也就是你会写一个类,明白类所产生的对象中包含的是他的数据成员(无虚函数的时候).而类的成员函数则在SIZEOF(类)是不在其中,是因为每个同类的对象在执行同样的函数时都是相同的函数体,如果为没个类在加上函数的占用,似乎不合情理.而对象的成员函数之所以能处理该对象的数据成员,是因为成员函数传递了一个THIS 指针.当然你还要知道继承,以及没有虚函数的情况下的一系列问题,例如名字冲突,继承后的模型等等.
现在来看含有虚函数的类.
CLASS A{
int m_a;
fun();
virtual vfun();
};
sizeof(A)=8 这是因为如果类有虚函数,编译器会为类产生一个虚表VTABLE 而类则在每个对象的首地址初产生一个虚表指针,在动态绑定后,通过虚表指针调用它所指向的虚表中的对应的虚函数
若用类A 定义一个对象 a, 此时a 的模型为
VPTR* 虚表指针 4个字节
m_a 4个字节.
而对象a的虚表指针和虚表的模型大概为
------------------- -----------------------
| VPTR* |-------------------> | class a:: vfun() |
------------------- -----------------------
| a |
-------------------
如果我用B类做为基类的公共派生类
CLASS B{
int b;
vfun(); 重写了基类的VFUN()函数
VIRTUAL VFUN2();
};
此时B类对象的模型为
虚表
VPTR* --------------> VFUN() 虚表顺序按类中声明顺序
a VFUN2()
b
于是当A *P被赋予一个B类对象时,当调用VFUN()函数时,因为为虚函数,所以要通过虚表索引,找到索引后在通过虚表内的函数地址,找到该类的虚函数.又因为给指针赋予的是B类对象所以此时是通过对象B的VTABLE找到函数,当然就是B类重写的虚版本了
在说一下 对象限制
有这么一段代码
CLASS A{
INT A;
FUN( VFUN() );
VIRTUAL VFUN();
};
CLASS B{
INT B
VFUN();
};
CLASS C{
INT A;
INT C;
};
如果有A a; B b ; C c;
C.FUN() 调用的显然是A::FUN() 但FUN()里的VFUN()是虚函数又是调用的是谁的那,当然是C类的了,因为此时VPTR*是指向C类的VTABLE ,但是C类没有重写VFUN()所以是调用的继承于B类的虚版本.
例如 A *P 给P赋予一个C类对象,同样此时对象的VPTR指向C了虚表
但当(A)C.VFUN();这时调用的就是A的了,因为对象向上转型是被切除的,从VPTR来看就是VPTR指向了A的虚表

本文深入探讨了C++中多态性的实现原理,包括虚函数、虚表和虚表指针的概念,解释了如何通过虚函数实现运行时多态,并讨论了对象限制及虚函数调用的具体过程。

被折叠的 条评论
为什么被折叠?



