7

有时我需要暴露一些班级成员。例如在下面的例子中class Mechanic可能需要直接访问Engine组件。我读过很多次,由于几个原因,所有字段都应该由 mutator(访问器)方法访问。但是在提供非常量引用 getter 时是否有任何优势:

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. 看起来,要完全遵守某些人的说法,您需要执行类似System.getInstance().getOut().println("hello world"). 在这种情况下,除了大量的官僚代码之外,我没有看到任何好处。

4

9 回答 9

3

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

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

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

}; // eo class Singleton
于 2010-11-06T15:59:56.340 回答
3

显式的 getter 和 setter可能过于官僚;这取决于你的情况。

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

如果您的课程非常简单(例如接近成为POD)并且不太可能更改,那么不必实现 getter 和 setter 可能不值得。

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

于 2010-11-06T16:02:24.333 回答
1

提供 getter 的一个优点是,当您决定更改 getter 的工作方式时,无需重新编译使用此类的代码。但是如果你有一个公共字段,后来决定做一个吸气剂,所有的代码都应该重新编译。除此之外,我认为没有任何严重的实际理由将您的变量设为私有。但是请注意,当且仅当您必须为外部用户提供一种获取引擎引用的方法时,这一切都成立。如果可以设计软件以完全消除这种需求,那就更好了。

于 2010-11-06T16:00:14.317 回答
1

正如我最近刚接触到的那样,getter 和 setter 散发出糟糕设计的味道。但是,如果您希望这样,提供获取和设置的功能m_engine(由您定义)而不是仅仅公开它(您无需干预)意味着您有一个插件点以供将来更改。

于 2010-11-06T17:16:52.747 回答
1

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

于 2010-11-13T12:38:21.520 回答
0

对我来说,这很有意义:

image(i,j) = 234;
于 2010-11-06T16:00:03.523 回答
0

与其考虑公开类的私有成员,不如多考虑在这些类上调用方法。我读了一篇有趣的 Java 文章,为什么 Getter 和 Setter 方法是邪恶的,它适用于 C++ 和 Java 一样。

于 2010-11-06T16:03:50.603 回答
0

是的,这是有道理的——对于可维护性、验证和一致性。

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

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

最后,您的代码将保持一致:您不必打开标题即可知道成员的可见性——您总是知道。这对模板也很有用。

于 2010-11-06T17:53:04.480 回答
0

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

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

您只想公开一个类发出的新数据。说Car.get_exhaust()Car没有排气,只产生它,当你这么问的时候。;)

或者,机械师将Fire Riefle.fire()无法访问 for ,就像这样:然后将调用 say 。XDRiefle::TriggerTrigger.fix_by(Mechanic)fix_byMechanic.add_working_hour(0.5)

于 2012-11-14T18:05:27.260 回答