《C++ Primer 5th》中Derived-to-Base转换可访问性的技术疑问
派生类到基类转换可访问性的示例说明
针对《C++ Primer 5th》里的后两个要点,用代码示例逐个解释:
要点2:无论派生类以何种方式继承基类,派生类自身的成员函数和友元都可以使用Derived-to-Base转换
不管派生类是public、protected还是private继承基类,它自己的成员和友元都能自由地把派生类对象转换成基类类型。
示例代码(private继承场景)
#include <iostream> using namespace std; class Base { public: void baseFunc() { cout << "调用基类方法" << endl; } }; // 以private方式继承Base class Derived : private Base { public: void derivedMemberFunc() { // 派生类成员函数中,将自身转换为Base*,合法 Base* basePtr = this; basePtr->baseFunc(); } }; // Derived的友元函数 void derivedFriendFunc(Derived& d) { // 友元函数中,将Derived对象转换为Base*,合法 Base* basePtr = &d; basePtr->baseFunc(); } int main() { Derived d; d.derivedMemberFunc(); // 正常输出:调用基类方法 derivedFriendFunc(d); // 正常输出:调用基类方法 // 注意:用户代码(main函数属于用户代码)无法转换,会编译报错 // Base* invalidPtr = &d; return 0; }
这个例子里,Derived是private继承Base,但它自己的成员函数和友元都能完成Derived到Base的转换,调用基类方法。
要点3:若派生类D以public/protected方式继承基类B,则D的派生类的成员函数和友元可以使用转换;若D是private继承,则不行
当继承链变长时,是否能转换要看中间派生类的继承方式:如果中间层是private继承,那么更下层的派生类就无法访问这个转换路径。
示例1:public继承场景(允许下层派生类转换)
#include <iostream> using namespace std; class Base { public: void baseFunc() { cout << "调用基类方法" << endl; } }; // 以public方式继承Base class Derived : public Base {}; // 从Derived派生的类 class Derived2 : public Derived { public: void derived2MemberFunc() { // Derived2的成员函数中,将自身转换为Base*,合法 Base* basePtr = this; basePtr->baseFunc(); } }; int main() { Derived2 d2; d2.derived2MemberFunc(); // 正常输出:调用基类方法 return 0; }
这里Derived是public继承Base,所以Derived2作为Derived的派生类,它的成员函数可以顺利完成Derived2到Base的转换。
示例2:private继承场景(禁止下层派生类转换)
#include <iostream> using namespace std; class Base { public: void baseFunc() { cout << "调用基类方法" << endl; } }; // 以private方式继承Base class Derived : private Base {}; // 从Derived派生的类 class Derived2 : public Derived { public: void derived2MemberFunc() { // 下面的代码会编译报错!因为Derived是private继承Base,Derived2无法访问Derived到Base的转换 // Base* basePtr = this; // basePtr->baseFunc(); } }; int main() { Derived2 d2; // d2.derived2MemberFunc(); // 内部代码编译不通过,无法运行 return 0; }
这个例子里,Derived是private继承Base,Derived2作为下层派生类,它的成员函数无法完成Derived2到Base的转换,因为Derived把Base的继承权限设为private,切断了下层派生类的访问路径。
内容的提问来源于stack exchange,提问作者yapkm01
相关产品推荐
相关产品推荐

