【问题标题】:C++ Private Nested Abstract ClassC++ 私有嵌套抽象类
【发布时间】:2011-02-16 07:05:26
【问题描述】:

所以也许这是一个愚蠢的问题,我想多了,但我有以下情况。我正在制作一个“class Shell”,它可以运行抽象的“class Action”对象。它是唯一应该创建或使用这些对象的类。 Action 对象需要访问 Shell 才能对其执行特定操作,但我试图避免为此添加公共接口(不应允许其他人这样做)。

我原本有一个简单的(不那么优雅)

class Shell
{
 public:
    bool checkThing();
    // etc...
 private:
    bool _thing;
};

class Action
{
 public:
    virtual void execute( Shell &s )=0;
};

class ChangeAction : public Action
{
 public:
    void execute( Shell &s )
    {
        // requires friendship or public mutator!
        s._thing = true;
    }
};

所以我考虑了一个嵌套类 Action,但我想将其设为私有(为什么要让除了 Shell 之外的任何其他人做出具体的 Action,对吧?)

class Shell
{
 public:
    bool checkThing();
    // etc...
 private:
    bool _thing;
    class Action;
};

class Shell::Action
{
 public:
    virtual void execute( Shell &s )=0;
};

class ChangeAction : public Shell::Action
{
 public:
    void execute( Shell &s )
    {
        // ok now!
        s._thing = true;
    }
};

但我当然不能再从 Action 继承(这是有道理的,它是私有的)。所以这行不通。

所以我的问题是,我应该使用第一种方法和友谊还是公共界面?我可以使用类似于第二种方法的方法来保持与 Actions 和 Shell 的关系吗? 你有更好的主意吗?

【问题讨论】:

    标签: c++ inheritance friend nested-class


    【解决方案1】:

    如果需要能够看到Action 的唯一代码是Shell,则一种选择是在头文件中前向声明Action,但只在.cpp 文件中定义类。这将允许您在实现文件中声明任意数量的Action 子类,而不会让其他任何人从Action 子类化,因为没有其他人会拥有Action 的完整类定义。这也避免了对公共接口或 friend 声明的任何需要 - 所有 Action 类都在全局范围内声明,但由于在 .cpp 文件中声明而与其他文件屏蔽。

    顺便说一句,好问题!

    【讨论】:

    • 如果 Shell 需要创建具体的 Action 类怎么办?使用这种方法,Shell 不知道具体的类,所以看起来我需要一个工厂。那属于哪里呢?起初我以为 Shell 会自己处理这个问题,但我需要一个单独的工厂类吗?感谢您的建议!
    • @Matt- 如果所有动作都在 .cpp 文件中与 Shell 的代码一起声明,那么 Shell 应该能够直接实例化它们。如果你愿意,你也可以建立一个工厂,但如果你这样做也应该放在 .cpp 文件中。这个想法是将所有实现细节保留在 .cpp 文件中,其他部分的代码看不到它们。
    • 对不起,我以为我明白这一点,但我有点困惑。 Action 是否应该仍然是 Shell 的嵌套类?你说我不需要让Action成为Shell的朋友,但是如何让Action的子类访问Shell的私有成员呢?
    • @Matt- 啊,如果 Action 需要查看 Shell 的私有内部,如果您不想将类的内部公开给所有人,那么您将不得不与它成为朋友.我没有注意到这个要求。
    • 好的,谢谢,这看起来确实是个好方法。我一直在重新考虑为 Actions 需要的东西添加一个公共接口,因为它们并没有通过公开它们来完全违反封装,而且我更喜欢它而不是让 Action 访问 Shell 的私有数据。不过,感谢您的帮助!
    【解决方案2】:

    您可以使用这些方法的组合:基本上只需从第一个方法中获取所有类并将它们移动到 Shell 类的私有部分:

    class Shell {
    public:
        bool checkThing();     // etc...
    private:
        bool _thing;
    
        class Action {
        public:
            virtual void execute( Shell &s )=0;
        };
    
        class ChangeAction : public Action
        {
        public:
            void execute( Shell &s )
            {
                // ok now!         s._thing = true;
            }
        }; 
    
    };
    

    【讨论】:

      猜你喜欢
      • 2011-07-30
      • 1970-01-01
      • 2017-02-10
      • 2014-08-16
      • 2016-05-08
      • 1970-01-01
      • 2015-08-01
      • 1970-01-01
      相关资源
      最近更新 更多