有没有办法确保继承的成员在派生类中不可访问,同时仍然保持公共继承的好处?

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
;

您还可以通过其他方式更改访问模式,例如从protectedpublic。这是godbolt.org 的示例。

但是请注意,派生自Base2 的类仍然可以通过此名称访问Base1::baseMember_。这将绕过Base2 中的访问检查。他们将无法通过baseMember_ 的非限定名称访问它。您可能希望使用从 Base1usingBase2 的私有继承 - 在 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 我知道这一点,我只是措辞有点错误。我现在已经对其进行了编辑,因此它讨论了派生类中无法访问的成员

以上是关于有没有办法确保继承的成员在派生类中不可访问,同时仍然保持公共继承的好处?的主要内容,如果未能解决你的问题,请参考以下文章

继承知识总结

C++_练习—继承_公有继承

类的继承

通过基类指针C++访问派生类的成员

c++继承是如何工作的?

实验五 类的继承派生和多态