类接口查询

Class interface query

本文关键字:查询 接口      更新时间:2023-10-16

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

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

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

谢谢你的帮助!

如果您的类包含可供他人使用的对象,请将其公开。封装意味着隐藏执行某些操作所需的变量。某些数据成员不属于此范围。

示例:

汤姆;

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

人可以隐藏一切,但会很麻烦:

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

如果您想将接口仅限于方法,那么请将对象保持为私有对象,并使用访问器方法向私有对象返回const引用(如果需要,还可以返回非常数)。

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

这取决于你在做什么。如果我正确理解你的问题,我个人更倾向于让Object成为ObjectManager的私有成员,并向ObjectManager添加一个函数作为Object::getName()的代理。(这是你的问题吗。这取决于,但更有可能的是,继续将其私有化并添加额外的功能。请注意,这个答案是基于这样一个假设,即您将在这里大量使用继承。

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

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

正如您所看到的,我将方法头更改为与ObjectManager相关的描述性。这种类型的方法命名可以方便地将对象内部更复杂的交互抽象出来。

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