7

所以也许这是一个愚蠢的问题,我想多了,但我有以下情况。我正在制作一个可以运行抽象“类动作”对象的“类 Shell”。它是唯一应该创建或使用这些对象的类。操作对象需要访问 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 的关系吗?你有更好的主意吗?

4

2 回答 2

4

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

顺便说一句,好问题!

于 2011-02-16T07:08:56.210 回答
0

您可以使用这些方法的组合:基本上只需从第一个方法中获取所有类并将它们移动到 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-02-16T07:11:22.503 回答