c++ 提供非常量引用getter有意义吗

0md85ypi  于 2023-05-02  发布在  其他
关注(0)|答案(9)|浏览(103)

有时我需要公开一些类成员。例如,在下面的示例中,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时,Java中也有类似的东西。看起来,要完全符合某些人的说法,您需要执行像System.getInstance().getOut().println("hello world")这样的调用。在这种情况下,除了大量的官僚代码外,我看不到任何好处。

bbuxkriu

bbuxkriu1#

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

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

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

}; // eo class Singleton
ztyzrc3y

ztyzrc3y2#

显式的getter和setter * 可能 * 过于官僚;那要看你的情况。
使用getter和setter函数的主要原因是,它将类的客户端与未来实现中的潜在更改隔离开来(例如,考虑一下如果您决定按需生成Engine对象(而不是使用成员变量),或者决定将其隐藏在智能指针或其他容器之后会发生什么)。
如果你的类很简单(e。例如,接近于POD)并且不太可能改变,那么它可能不值得实现getter和setter。
然而,为了回答你的问题,一个 non-const getter可能没有多大意义。你的getter原型应该是Engine & engine() const;否则你将无法在constCar对象上调用它。

oprakyz7

oprakyz73#

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

ohfgkhjo

ohfgkhjo4#

正如我最近碰巧接受的教育一样,getter和setter闻起来很糟糕。但是,如果您希望这样做,那么提供获取和设置m_engine(由您定义)的函数而不仅仅是公开它(您没有干预)意味着您有一个插件点用于将来的更改。

e4yzc0pl

e4yzc0pl5#

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

fv2wmkja

fv2wmkja6#

对我来说,这在这里是有意义的:

image(i,j) = 234;
velaa5lx

velaa5lx7#

与其考虑公开类的私有成员,不如更多地沿着调用这些类的方法。我读过一篇有趣的Java文章Why Getter and Setter Methods are Evil,它同样适用于C++和Java。

3pvhb19x

3pvhb19x8#

是的,这是有意义的--对于可维护性、验证性和一致性。
将来可能需要更改类的许多方面,提供访问器有助于最大限度地减少客户端代码的损坏。
你可以在这里输入所有你需要的验证逻辑,以确保引擎是一个有效的指针,不是在一个不可用的状态,等等。
最后,你的代码将是一致的:你不需要打开页眉就能知道成员的可见性-你总是知道的。这对于模板也是有用的。

jrcvhitl

jrcvhitl9#

在这种情况下,你需要一个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

相关问题