diff --git a/README.md b/README.md index 0670388..08cf318 100644 --- a/README.md +++ b/README.md @@ -517,7 +517,29 @@ virtual int A() = 0; Data vall = { 0, "Anna" }; ``` -### 虚继承、虚函数继承 +### 虚继承、虚函数 + +#### 虚继承 + +虚继承用于解决多继承条件下的菱形继承问题(浪费存储空间、存在二义性)。 + +底层实现原理与编译器相关,一般通过**虚基类指针**和**虚基类表**实现,每个虚继承的子类都有一个虚基类指针(占用一个指针的存储空间,4字节)和虚基类表(不占用类对象的存储空间)(需要强调的是,虚基类依旧会在子类里面存在拷贝,只是仅仅最多存在一份而已,并不是不在子类里面了);当虚继承的子类被当做父类继承时,虚基类指针也会被继承。 + +实际上,vbptr指的是虚基类表指针(virtual base table pointer),该指针指向了一个虚基类表(virtual table),虚表中记录了虚基类与本类的偏移地址;通过偏移地址,这样就找到了虚基类成员,而虚继承也不用像普通多继承那样维持着公共基类(虚基类)的两份同样的拷贝,节省了存储空间。 + +#### 虚继承与虚函数 + +* 相同之处:都利用了虚指针(均占用类的存储空间)和虚表(均不占用类的存储空间) +* 不同之处: + * 虚继承 + * 虚基类依旧存在继承类中,只占用存储空间 + * 虚基类表存储的是虚基类相对直接继承类的偏移 + * 虚函数 + * 虚函数不占用存储空间 + * 虚函数表存储的是虚函数地址 + + + ### 内存分配和管理