C++关于虚类,虚函数以及友元的知识

关于虚类与虚继承

虚继承主要用于解决菱形继承问题,解决一个孙子类继承爷爷类两次的问题。防止出现二义性。虚继承底层实现原理与编译器相关,一般通过虚基类指针和虚基类表实现,每个虚继承的子类都有一个虚基类指针(占用一个指针的存储空间,4字节)和虚基类表(不占用类对象的存储空间)(需要强调的是,虚基类依旧会在子类里面存在拷贝,只是仅仅最多存在一份而已,并不是不在子类里面了);当虚继承的子类被当做父类继承时,虚基类指针也会被继承。实际上,vbptr指的是虚基类表指针(virtual base table pointer),该指针指向了一个虚基类表(virtual table),虚表中记录了虚基类与本类的偏移地址;通过偏移地址,这样就找到了虚基类成员,而虚继承也不用像普通多继承那样维持着公共基类(虚基类)的两份同样的拷贝,节省了存储空间。

虚函数与虚指针

虚函数是C++表现多态性的一个重要呈现,关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。而虚函数就是通过动态绑定实现多态。
虚函数可以是内联函数,内联是可以修饰虚函数的,但是当虚函数表现多态性的时候不能内联。
内联是在编译器建议编译器内联,而虚函数的多态性在运行期,编译器无法知道运行期调用哪个代码,因此虚函数表现为多态性时(运行期)不可以内联。
inline virtual 唯一可以内联的时候是:编译器知道所调用的对象是哪个类,这只有在编译器具有实际对象而不是对象的指针或引用时才会发生。
与虚函数相关的是虚函数指针与虚函数表。
虚函数指针是指向虚函数表的,而虚函数表是存放虚函数地址的一个表,程序运行时会从该表中找到虚函数指针指向的函数进行调用,如果派生类实现了基类的某个虚函数,则在虚表中覆盖原本基类的那个虚函数指针,在编译时根据类的声明创建。而虚函数指针是存放在类的实例中的。虚函数表存放在类的实例的内存中。

友元

友元可以分为友元类和友元函数,友元的关系是单向的且不可继承。友元在一定程度上破坏了类的封装性,因为一旦一个类或者函数定义为某个类的友元,则可以访问该类的私有成员。友元只能在类中声明,但可以在任何地方定义,友元关键字只需要在声明的时候加入即可,这一点和内联函数恰好相反。

你可能感兴趣的:(新手)