提供非const引用getter是否有意义

时间:2010-11-06 15:56:17

标签: c++ oop getter accessor mutators

有时我需要公开一些班级成员。例如,在以下示例中,class Mechanic可能需要直接访问Engine组件。我已多次阅读过mutator(accessor)方法应该访问的所有字段,原因有很多。但是在提供非const参考吸气剂时是否有任何优势:

class Car
{
    public:
        Engine & engine()
        {
           return m_engine;
        }

        //as a consequence you will also need to provide const version
        const Engine & engine() const
        {
           return m_engine;
        }

    private:
       Engine m_engine;
}

简单地将引擎组件公开:

class Car
{
    public:
        Engine engine;
}

如果您不喜欢此示例,也可以将public替换为protected。在现实生活中,当涉及System.inSystem.out时,你在Java中有类似的东西。看起来,要完全符合某些人的说法,您需要执行System.getInstance().getOut().println("hello world")之类的调用。在这种情况下,除了很多官僚代码外,我没有看到任何好处。

9 个答案:

答案 0 :(得分:3)

当您返回的值实际上在堆上时,它们会很有用。

template<class T> class Singleton
{
private:
    static T* m_pSingleton;

public:
    T& getSingleton() { assert(m_pSingleton); return(*m_pSingleton); };

}; // eo class Singleton

答案 1 :(得分:3)

明确的getter和setter 可以过分官僚主义;这取决于你的情况。

具有getter和setter函数的主要原因是它将您的类的客户端与将来可能的实现更改隔离开来(例如,考虑如果您决定生成Engine对象会发生什么按需(而不是使用成员变量),或决定将其隐藏在智能指针或其他容器后面。

如果你的课程非常简单(例如接近POD)并且不太可能改变,那么实施吸气剂和制定者可能不值得。

但是,要回答你的问题,非const getter可能没有多大意义。你的getter原型应该是Engine & engine() const;否则,您将无法在const Car个对象上调用它。

答案 2 :(得分:1)

提供getter的一个优点是,当您决定更改getter的工作方式时,不需要重新编译使用此类的代码。但是如果你有一个公共字段,后来决定制作一个getter,那么所有的代码都应该重新编译。除此之外,我没有看到任何严重的实际理由让你的变量私有化。但请注意,当且仅当您必须为外部用户提供引用引擎的方法时,这一切都成立。如果可以设计软件以便根本不需要这样做,那就更好了。

答案 3 :(得分:1)

因为我最近接受了最近的教育,吸气鬼和制定者闻到了糟糕的设计。但是,如果你想这样做,提供函数来获取和设置m_engine(由你定义)而不是仅仅暴露它(你没有干预)意味着你有一个插件点用于将来的更改。 / p>

答案 4 :(得分:1)

我找到了提供这种吸气剂的合理意义。它使您的软件集成更容易(例如,当您想要将界面翻译成另一种语言并绑定ABI时)。

答案 5 :(得分:0)

对我而言,这里有道理:

image(i,j) = 234;

答案 6 :(得分:0)

而不是考虑暴露一个类的私有成员更多地考虑在这些类上调用方法。 我读了一篇有趣的Java文章Why Getter and Setter Methods are Evil,它与C ++一样适用于Java。

答案 7 :(得分:0)

是的,它有意义 - 可维护性,验证和一致性。

您可能需要在将来更改该类的许多方面,提供访问器可以帮助最大限度地减少客户端代码的破坏。

您可以输入此处所需的所有验证逻辑,以确保引擎是有效指针,不处于不可用状态等。

最后,您的代码将保持一致:您无需打开标题即可了解成员的可见性 - 您只需知道。这对模板也很有用。

答案 8 :(得分:0)

在这种情况下,您宁愿需要Car.fix(const Mechanic&)函数,然后将引擎提供给Mechanic,例如:Engine.fix(const Mechanic&),因为我认为Engine的状态将被修改。

使用类的最初想法是将数据与其访问器功能联系在一起。如果您执行仅返回内部数据的setter或getter,则表示您的数据未与其访问者功能绑定在一起:您的类不完整。

您只想公开类发布的新数据。当你提出要求时,说Car.get_exhaust()并且Car没有排气,只产生它。 ;)

Fire Riefle.fire(),而Riefle::Trigger的访问权限不会被机制修复:Trigger.fix_by(Mechanic),然后fix_by会调用Mechanic.add_working_hour(0.5)。 XD