【问题标题】:C++ subclass accessC++ 子类访问
【发布时间】:2011-09-10 15:33:15
【问题描述】:

我有一个由许多子类继承的主类。继承的主类必须至少在继承中受到保护,以防止非派生类通过子类使用或更改它。

有没有办法允许各个子类更改彼此继承的主类变量,但不允许公共访问主类?如果不使用给出的friend关键字,这将产生复杂的代码。

在完整的上下文中:

我有一个节点类,可以添加/删除相对于它的节点。有一个依赖于节点类的列表类(和子类),这意味着节点不能公开访问,以防它也破坏了类列表。节点也必须可以访问以列出帮助程序类。

为了确保发生这种情况,我在另一个类 accessnode 中实现了受保护的节点。所有想要节点权限的类都将 accessnode 继承为受保护的(因此 accessnode 类不是公共的)。这意味着助手和列表类/子类都可以访问节点。

问题是,为了让 TemplateList 以只读方式复制 CharList(TemplateList 的子类),它需要访问 CharList 的节点(以避免使用 CharList 的迭代器) - 问题是,节点是受保护的(以防止外部的、非访问节点的干扰),并实现一个授予节点访问权限的公共方法将失败。

我需要的是侧向继承,所以 accessnode 类型的所有子类都可以访问彼此的节点,而无需公开授予访问权限。

简而言之:

(受保护的)AccessNode 内的节点。
模板列表:受保护的访问节点。
CharList : 受保护的访问节点。
TemplateList 需要访问 CharList 的 AccessNode。
AccessNode/Node 不能公开。

【问题讨论】:

  • 你在用这个类层次建模什么?
  • 在这里同意赛斯;也许更好地陈述目标,而不是你的第一步。
  • 我已经更新了问题。试图澄清。

标签: c++ inheritance subclass


【解决方案1】:

免责声明:这与这个特定问题完全无关,而是更多关于从今天开始引导您提出这个问题和其他问题的一般问题。

我认为你在这里对着错误的树吠叫。我感觉您提供了对列表内部节点的访问权限,然后期望节点类型本身可以保护列表免受粗心修改(即那些可能破坏列表不变量的修改)。这样做,您正在为一个更简单的问题寻求一个复杂的解决方案:首先不要让用户访问节点。

如果您查看 STL 提供的有关容器和特定列表的方法,事情就会变得简单得多。该列表是根据一些未知的不可访问节点来实现的。这些节点操作上的访问说明符根本无关紧要,因为用户无法访问对象本身,因此它们可以是公共的。用户通过不同的代理(iteratorconst_iterator 类型)获得对列表内容的访问权,该代理只提供那些不会弄乱列表状态的操作。

【讨论】:

  • 问题更多的是没有定义的范式允许子类共享对主类继承的访问而不公开它。这个(我的)解决方案尝试的复杂性告诉我它不是正确的,因为解决方案应该真正流动。
  • @SSight3:正如大卫所写,这不是您问题的答案。所以你不应该选择它作为解决方案。我非常同意大卫的观点,这是你能得到的最好的一般建议(我记得我之前给过你同样的建议,我确实在我很简短的回答中给出了这个方向的建议),但是这个回应 不是技术问题的答案,因此不应标记为该问题的解决方案。例如,人们在谷歌上搜索如何按照您的要求进行操作,不会在此回复中找到技术解决方案。如果他们最终来到这里。
  • 我也同意这不是对发布的技术问题的回答,不应被选为接受。关于@SSight3 的评论:我不能同意,您是否认为问题可能出在您的设计上?也就是说,几乎所有东西都可以用几乎任何语言来实现,但是设计必须考虑到你想要实现它的语言。例如,如果您要在 python 中对此进行编码,那么问题会在于该语言中根本没有访问说明符吗?在 C++ 中有一些很好的列表实现...
【解决方案2】:

我不完全确定我理解您所说的“子类 [to] 更改彼此继承的主类变量”是什么意思。

如果您只想允许派生类访问基类成员变量,则将成员变量设为protected。和/或添加 protected 访问器函数。

如果您希望派生类的不同实例修改基类中保存的共享数据,那么您可以将static protected 成员变量添加到基类。所有实例都将共享同一个成员变量。

如果你能澄清问题会有所帮助。

【讨论】:

    【解决方案3】:

    您始终可以在顶级类中添加一个 protected 访问器函数,但与其这样做,不如重新考虑设计。

    编辑:具体示例:

    class Base
    {
    protected:
        struct State
        {
            int     m1;
            char    m2;
    
            State(): m1(), m2() {}
        };
    
        State   state_;
    
        static State& state( Base& o) { return o.state_; }
    };
    
    class Derived
        : public Base
    {
    public:
        void foo( Base& other )
        {
            Base::State&    baseState   = state( other );
            // Blah blah.
        }
    };
    
    int main()
    {
        Derived o;
        // Blah blah.
    }
    

    干杯,

    【讨论】:

    • 这无济于事:如果D1D2 都继承自B,那么D1 无法访问D2::B 的受保护成员。
    • 好吧,也许你可以更详细地说明你的答案,以明确它是如何工作的。或者,也许 OP 应该首先让她的问题更准确一些。 :-)
    • @Kerrek:“那无济于事”是不正确的,我很抱歉。 “如果......不能......”也是不正确的(虽然它对于直接访问是正确的,但它不适用于通过成员指针访问),非常抱歉。我应该包括一个例子,但认为没有必要。 :-( 但是,我现在正在这样做。希望这会有所帮助。干杯,
    猜你喜欢
    • 2018-07-28
    • 1970-01-01
    • 2012-06-19
    • 2011-06-13
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    相关资源
    最近更新 更多