虚表和菱形虚拟继承
c++中虚函数的主要作用就是实现多态,简单说父类的指针/引用调用重写的虚函数,当父类指针/引用指向父类对象时调用的是父类的虚函数,指向子类对象时调用的是子类的虚函数。virtual就是为了解决继承的二义性问题。
1.继承,继承是面向对象复用的重要手段。通过继承定义一个类,继承是类型之间的关系建模,共享公有的东西,实现各自本质不同的东西。继承可以是单一继承或多重继承,每一个继承连接可以是public,protecte,private。
单继承--一个子类只有一个直接父类时称这个继承关系为单继承;
多继承--一个子类有两个或以上直接父类时称这个继承关系为多继承;
2.多态
a.静态多态就是重载,因为是在编译期决议确定,所以称为静态多态。
b.动态多态就是通过继承重写基类的虚函数实现的多态,因为是在运行时决议确定,所以称为动态多态。
3.菱形虚拟继承
菱形虚拟继承的模式
class A;
class B : virtual public A;
class C : virtual public A;
class D : public B , public;
单一的虚拟继承
a.
class Base
{
private:
int _a;
};
class Derived : virtual public Base
{
};
虚拟继承时,在派生类的对象内存中会产生一个指向虚基表的指针,所以
sizeof(Base )=4; sizeof(Base ) = _a;
sizeof(Derived )=8; sizeof(Derived ) =_a + Derived 中的指向虚基表的指针;
b.
class Base
{
public:
virtual void funl()
{
cout << "Base::fun1()" << endl;
}
private:
int _a;
};
class Derived : virtual public Base
{
public:
virtual void funl()
{
cout << "Derived::fun1()" << endl;
}
virtual void Derivedfun2()
{
cout << "Derived::Derivedfun2()" << endl;
}
};
虚基类的虚表指针是不会被派生类所共享的,若派生类中含有新的虚函数(改写的不算),将会自己产生一个指向自己虚表的指针
sizeof(Base) =_a + Base 中 指向 虚函数表的指针
sizeof(Base) =8;
sizeof(Derived ) =Derived 的虚函数表指针 + Derived 中的指向虚基表的指针 + Base的虚函数表指针+_a
sizeof(Derived) =16;