C++私有嵌套抽象类

发布于 2024-10-17 21:38:24 字数 1093 浏览 11 评论 0原文

所以也许这是一个愚蠢的问题,我想太多了,但我有以下情况。我正在制作一个“类 Shell”,它可以运行抽象的“类 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之外的其他人制作具体的Actions,对吧?)

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继承不再有(这是有道理的,它是私人的)。所以那是行不通的。

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

So maybe this is a dumb question and I'm over thinking this, but I have the following situation. I am making a "class Shell" which can run abstract "class Action" objects. It is the only class that should create or use these objects. Action objects need access to the Shell to perform specific actions on it, but I'm trying to avoid adding public interfaces for this (no one else should be allowed to do that).

I originally had a simple (not so elegant)

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;
    }
};

So I considered a nested class Action, but I wanted to make it private (why let anyone else make concrete Actions except the Shell, right?)

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;
    }
};

But of course I can't inherit from Action any more (that makes sense, it's private). So that doesn't work.

So my question, should I just go with the first method and friendship or a public interface? Can I use something similar to the second method to keep that relationship with Actions and the Shell?
Do you have a better idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吃兔兔 2024-10-24 21:38:24

如果唯一需要能够看到 Action 的代码是 Shell,一种选择是在头文件中转发声明 Action,但仅在 .cpp 文件中定义类。这样,您就可以在实现文件中声明任意数量的 Action 子类,而无需让任何其他人从 Action 继承子类,因为没有其他人会拥有完整的类Action 的定义。这也避免了对公共接口或 friend 声明的任何需要 - 所有 Action 类都在全局范围内声明,但由于在 . .cpp 文件。

顺便说一句,好问题!

If the only code that needs to be able to see Action is Shell, one option would be to forward-declare Action in the header file but only define the class in the .cpp file. This would then let you declare as many Action subclasses as you'd like in the implementation file without letting anyone else subclass off of Action because no one else would have a complete class definition for Action. This also avoids any need for public interfaces or friend declarations - all the Action classes are declared in the global scope, but shielded from other files by virtue of being declared in the .cpp file.

Great question, by the way!

梦里°也失望 2024-10-24 21:38:24

您可以使用这些方法的组合:基本上只需从第一个方法中取出所有类并将它们移动到 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;
        }
    }; 

};

You can can use a combination of the methods: Basically just take all your classes from the first method and move them into the private section of the Shell class:

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;
        }
    }; 

};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文