注意:本文有时候会用Visual Studio Code里插件的自动补全功能来展示访问权限的范围(当且仅当自动补全范围等价于对象访问权限范围的时候),但是不代表日常使用时只要是出现在自动补全范围内的可调用对象/成员都是可访问的的。
一,公有继承
#include<cstdio> #include<iostream> #include<string> #include<algorithm> #include<vector> class Base{ public: int PublicBase; void PublicPrint() {std::cout << "PublicPrint()" << std::endl;} protected: int ProtectedBase; void ProtectedPrint() {std::cout << "ProtectedPrint()" << std::endl;} private: int PrivateBase; void PrivatePrint() {std::cout << "PrivatePrint()" << std::endl;} }; class Derived : public Base{ public: void DerivedPrint() { std::cout << "DerivedPrint()" << std::endl; std::cout << ProtectedBase << std::endl; //若要访问protected的数据成员需要通过派生类里的成员函数访问 PublicPrint(); ProtectedPrint(); } }; int main(void) { Derived der; der.PublicPrint(); der.PublicBase; //der.ProtectedBase; //不能直接访问protected数据成员 //der.ProtectedPrint();//意思同上 return 0; }
公有继承的派生类可以直接访问基类的public中的数据成员和成员函数,不能直接访问protected中的数据成员和成员函数,若要访问protected的数据成员需要通过派生类里的成员函数访问。基类里的private成员函数及数据成员派生类是没有访问权限的。但是我们可以通过间接调用Base::function()来访问Base类里的private对象。
派生类成员函数的访问权限一览:
用户的访问权限一览(非常显然了):
其实再添几行代码,很容易知道Derived的派生类访问权限(SeconedDerived类是Derived的公有继承):
二,保护继承
部分代码改变如下:
class Derived : protected Base{ public: void DerivedPrint() { std::cout << "DerivedPrint()" << std::endl; std::cout << ProtectedBase << std::endl; //若要访问protected的数据成员需要通过派生类里的成员函数访问 PublicPrint(); ProtectedPrint(); } };
通常保护继承的派生类访问基类成员的权限和公有继承的派生类访问基类成员的权限相同,保护继承的派生类对象访问父类成员的权限和私有继承子类对象访问父类成员的权限相同。(der是Derived实例)
可以看出派生类的访问权限并没有什么改变。但是派生类会将所有从基类继承的成员全部放到protected下。不多赘述。
三,私有继承
部分代码改变如下:
class Derived : private Base{ public: void DerivedPrint() { std::cout << "DerivedPrint()" << std::endl; } };
私有继承的过程中,基类中的public和protected属性的成员在派生类中虽然能被访问,但是其属性在派生类中被降级为private,可以当作Derived类的private来访问。
总结
对于三种继承,对基类里的private对象处理方式都是一致的,即对派生类都是不可访问的,但它确实被继承了,可以通过基类里的函数来访问。三种继承的不同之处在于:公有继承是将基类的public和protected成员直接继承不改变其属性(即继承后依然是public和potected的),保护继承将基类的public和protected成员直接继承为派生类的protected成员。而私有继承则直接将基类的protected和public成员继承为派生类的private成员。
不难发现,存在着这样的一个优先级:private > protected > public,举个例子:
①当继承方式为public时,派生类里所继承的成员就是基类里对应成员的属性(public优先级最低覆盖不了其它关键字)
②当继承方式为protected时,派生类里所继承的成员属性只有public会改变为protected(优先级protected > public,protected能覆盖public)
③当继承方式为private时,派生类里所继承的成员属性全为private(private优先级最高,相当于覆盖了其它两个优先级)。