有没有办法确保继承的成员在派生类中不可访问,同时仍然保持公共继承的好处?
Posted
技术标签:
【中文标题】有没有办法确保继承的成员在派生类中不可访问,同时仍然保持公共继承的好处?【英文标题】:Is there a way to make sure inherited member is not accessible in derived classes, while still keeping the benefits of public inheritance? 【发布时间】:2021-01-13 16:12:56 【问题描述】:如果我有一个类包含派生类将继承的受保护成员:
class Base1
protected:
int baseMember_;
;
class Base2 : public Base1
public:
void printBaseMember
std::cout << baseMember_ << std::endl;
;
如何确保baseMember_
在派生自Base2
的类中不可访问?
显而易见的解决方案是简单地将继承设为私有:
class Base2 : private Base1
,
但这在我的情况下不起作用。原因是私有继承消除了 Base2 和 Base1 之间的 is-a 关系,这是我需要的,因为我需要在我的代码中的多个位置将Base1*
类型的对象分配给Base2*
。
有没有办法确保派生类不能访问受保护的成员,同时仍然使用公共继承?
【问题讨论】:
您可能拥有私有成员并创建派生类friend
。
你考虑过用组合代替继承吗?这将立即解决您的问题。
你的措辞有点混乱,因为成员总是被继承的,不管他们的访问权限是什么,唯一的区别是他们是否可以被访问
你能用一个真实的例子来激发这个吗?听起来您正在尝试打破可替代性(查找 Liskov 原则)
@largest_prime_is_463035818 你说得对,我会改变措辞。谢谢
【参考方案1】:
有没有办法确保派生类不能访问受保护的成员,同时仍然使用公共继承?
您可以通过using
声明更改继承成员的访问模式:
class Base1
protected:
int baseMember_;
;
class Base2 : public Base1
public:
void printBaseMember()
std::cout << baseMember_ << std::endl;
private:
using Base1::baseMember_; // baseMember_ is private in the context
// of Base2; its derived classes cannot access it
;
您还可以通过其他方式更改访问模式,例如从protected
到public
。这是godbolt.org 的示例。
但是请注意,派生自Base2
的类仍然可以通过此名称访问Base1::baseMember_
。这将绕过Base2
中的访问检查。他们将无法通过baseMember_
的非限定名称访问它。您可能希望使用从 Base1
和 using
对 Base2
的私有继承 - 在 Base2
中声明 Base1
的所有公共成员以缓解这种情况。
【讨论】:
孩子们仍然可以通过名字Base1::baseMember_
访问会员。我不确定 OP 是否关心这一点。
@eerorika 如果您在谈论 Base1 的孩子,那么是的,他们仍然可以访问它,这就是重点。该 baseMember_ 应该可以在从 Base1 派生的类中访问,但不能在从 Base1 的孩子派生的类中访问
@JensB 从Base1
的孩子派生的类确实可以通过这个名字访问Base1::baseMember_
。这将绕过Base2
中的访问检查。他们将无法通过 baseMember_
的非限定名称访问它。
@JensB:这就是重点。如果您从 Base2 派生,您仍然可以访问 Base1::baseMember_。所以我的观点不满足要求。
@Klaus 现在我明白了。没有考虑到这一点。你有更好的解决方案吗?【参考方案2】:
如何确保 baseMember_ 在派生自 Base2 的类中不可访问?
通过声明成员private
。您可以将Base2
声明为Base1
的朋友,这样它仍然可以访问。
【讨论】:
什么意思?我需要从 Base1 继承的其他类中的该变量,这就是它首先存在的原因 @JensB 一个成员存在于一个类的所有实例中。它不能仅在某些情况下选择性地存在。听起来您希望这些类有不同的基础。 @JensB:多重继承会很有帮助。 @eerorika 我知道这一点,我只是措辞有点错误。我现在已经对其进行了编辑,因此它讨论了派生类中无法访问的成员以上是关于有没有办法确保继承的成员在派生类中不可访问,同时仍然保持公共继承的好处?的主要内容,如果未能解决你的问题,请参考以下文章