C++为何允许类内this指针向私有基类转换实现多态而类外不行?
问题1:为什么派生类内部可以将this转换为私有基类指针,类外不行?
首先要明确C++私有继承的访问控制规则:
- 私有继承的本质是,基类的所有public/protected成员在派生类中会被视为派生类的私有成员,基类子对象本身也属于派生类的私有组成部分。
- C++的访问控制规则是:类的内部成员函数可以访问自身的所有私有成员,不受限制;类外部的代码无法访问该类的私有成员。
你在派生类Squire内部把this转成Shape*,本质是访问自己的私有基类子对象,属于类内访问私有成员,完全符合规则。而类外的main函数把Squire*传给需要Shape*的say函数,属于类外访问Squire的私有组成部分,当然会被编译器拦截。
问题2:第二个示例是否违反了封装性?
这并不是C++的设计缺陷,恰恰是符合封装规则的表现:
封装的核心是限制外部直接访问类的私有成员,但不会限制类的设计者主动选择对外暴露内部私有成员的引用/指针。
你可以把私有继承的基类子对象,等价于派生类的一个普通私有成员变量:
// 等价写法,和私有继承语义完全一致 class Derived { private: Base m_base; // 普通私有成员 public: void init() { worker_ = new Worker(&m_base); // 主动把私有成员的指针传给外部类 } // ...其余代码和你给出的例子一致 };
上述代码和你给出的私有继承版本逻辑完全等价,编译器当然不会报错,因为是你作为Derived类的设计者,主动在init这个public成员函数里把私有部分的指针泄露给了Worker。这种场景下如果编译器强制报错,反而会限制很多合理的实现需求,比如把内部私有的实现实例传给回调处理器,是非常常见的开发场景。
如果你的设计要求不允许泄露私有基类的指针,只需要不要在public成员函数里做这种转换即可,语言层面不需要也不应该替开发者做这种设计决策。
内容的提问来源于stack exchange,提问作者sake
相关产品推荐
相关产品推荐

