4

我一直想知道我已经为我的游戏引擎和游戏使用了很长一段时间的设计。假设我们有一个 Object 类

class Object
{
    public: 
        const std::string& getName() { return m_name; }

    private:
        std::string m_name;
}

然后,我有一个名为 ObjectManager 的类,它包含一个 Object 的实例。现在,我一直在想是否应该在 ObjectManager 中保持该实例为私有并复制代码,以便它可以调用 getName(),或者使 Object 公开,这违背了封装的概念。大家觉得哪个设计好呢?

谢谢你的帮助!

4

4 回答 4

1

如果您的类包含可供其他人使用的对象,请将其公开。封装意味着隐藏做某事所需的变量。某些数据成员不属于这种情况。

例子:

人汤姆;

    tom.getEyes().getColor();
    tom.getMouth().eat(tomato);
    tom.legs().walk();

Person 可以隐藏所有内容,但这会很麻烦:

    tom.getEyesColor(); // accessor for every eye feature
    tom.eat(tomato);   
    tom.walkAndEat();   // every possible combination of actions

进一步的例子:

    grid.row(3).col(5).setText("hello"); 

在这里,一个列类可以公开许多方法,而不必触及网格类。这就是面向对象编程的美妙之处。

如果您将类命名为 ObjectManager,我会感觉它正在为其他人管理 Object 实例,因此您应该公开它。使用继承的另一个想法也是有效的:

    class ObjectManager : public Object
    {
    };
于 2013-08-03T01:15:29.717 回答
0

如果您只想将接口限制为方法,则保持对象私有并使用访问器方法返回对私有对象的 const 引用(如果需要,则为非 const)。

此外,如果适用,继承也是一个不错的选择。

于 2013-08-03T00:44:12.213 回答
0

这取决于你在做什么。如果我正确理解您的问题,我个人更倾向于使 Object 成为 ObjectManager 的私有成员并向 ObjectManager 添加一个函数以充当 Object::getName() 的代理。(这是您的问题吗?)但是,如果您只是包装得特别薄,并且没有尝试做一些特别技术性的事情或您有什么,我可能会想以其他方式回答。这取决于,但更有可能的是,继续将其设为私有并添加额外的功能。请注意,此答案基于您将在此处大量使用继承的假设。

于 2013-08-03T00:56:30.490 回答
0

这真的取决于情况(抱歉没有回答!)。如果您确实想支持强封装,您可能希望 ObjectManager 看起来像这样:

public class ObjectManager
{
    private:
        Object obj;
    public:
        string GetNameOfInnerObject();
}

如您所见,我将方法标头更改为关于 ObjectManager 的描述性。这种类型的方法命名可以派上用场,将对象内部更复杂的交互抽象掉。

编辑:如果您告诉我们 ObjectManager 应该做什么,它可能会有所帮助。它是否有任何不直接对应于您的内部对象的方法?

于 2013-08-03T01:00:25.017 回答