提供非常量引用 getter 是否有意义

发布于 2024-10-01 15:12:32 字数 840 浏览 12 评论 0 原文

有时我需要揭露一些班员。例如,在下面的示例中,class Mechanic 可能需要直接访问Engine 组件。我已经多次读到,由于多种原因,所有字段都应该通过赋值器(访问器)方法访问。 提供非常量引用 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") 的调用。在这种情况下,除了大量官僚代码之外,我看不到任何好处。

Sometimes I need to expose some of the class members. For example in the following example class Mechanic may need direct access to Engine component. I have read many times that all fields should be accessed by mutator (accessor) methods because of several reasons. But is there any advantage when providing non-const reference 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;
}

over simply making engine component public:

class Car
{
    public:
        Engine engine;
}

You can also replace public with protected if you don't like this example. In real life you have something simillar in Java when it comes to System.in or System.out. It looks like, to be fully compliant on what some people say, you would need to perform calls like System.getInstance().getOut().println("hello world"). I don't see any benefit except a lot of bureaucratic code in such cases.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

梦里人 2024-10-08 15:12:32

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

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

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

}; // eo class Singleton

They can be useful when the value you are returning is actually on the heap.

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

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

}; // eo class Singleton
请你别敷衍 2024-10-08 15:12:32

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

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

如果你的类非常简单(例如接近于POD)并且不太可能改变,那么它可能不值得为实现 getter 和 setter 而费力。

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

Explicit getters and setters can be overly-bureaucratic; it depends on your situation.

The main cited reason for having getter and setter functions is that it isolates the clients of your class from potential changes in implementation in the future (for instance, consider what would happen if you decide to generate an Engine object on demand (rather than using a member variable), or decide to hide it behind a smart pointer, or some other container).

If your class if very simple (e.g. close to being a POD) and unlikely to change, then it may not be worth the faff of having to implement the getters and setters.

However, to answer your question, a non-const getter probably doesn't make much sense. Your getter prototype should be Engine & engine() const; otherwise you won't be able to call it on const Car objects.

烏雲後面有陽光 2024-10-08 15:12:32

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

One advantage of providing a getter is that when and if you decide to change the way the getter works, the code that uses this class need not be recompiled. But if you have a public field and later decide to make a getter, all code should be recompiled. Other than that I don't see any serious practical reason to make your variable private. However note that this all holds if and only if you have to provide a way for outer users to get a reference to the Engine. If it is possible to design the software so that this need be eliminated at all, that would be better.

秋凉 2024-10-08 15:12:32

正如我最近碰巧学到的那样,getter 和 setter 闻起来有糟糕的设计味道。但是,如果您希望这样,提供获取和设置 m_engine 的函数(由您定义)而不是仅仅公开它(您无需干预)意味着您有一个未来的插件点变化。

As I happened to get educated on recently, getters and setters smell of bad design. But, if you want it that way, providing functions to get and set m_engine (Defined by you) rather than just exposing it (You have no intervention) means that you have a plug-in point for future changes.

花之痕靓丽 2024-10-08 15:12:32

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

I have found reasonable point to provide such getter. It makes integration of your software easier (for example, when you want to translate interface into another language and bind ABIs).

深海少女心 2024-10-08 15:12:32

对我来说,这里是有道理的:

image(i,j) = 234;

For me it makes sense here:

image(i,j) = 234;
月下伊人醉 2024-10-08 15:12:32

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

Instead of thinking about exposing private members of a class think more along the lines of calling methods on those classes.
I read an interesting Java article, Why Getter and Setter Methods are Evil, which applies just as much to C++ as it does to Java.

客…行舟 2024-10-08 15:12:32

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

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

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

最后,你的代码将是一致的:你不必打开标头来知道成员可见性 - 您总是知道。这对于模板也很有用。

yes, it makes sense - for maintainability, validation, and consistency.

you may need to change many aspects of the class in the future, providing an accessor can help minimize breakage of client code.

you can enter all the validation logic you need here, to ensure that engine is a valid pointer, is not in an unusable state, etc.

finally, your code will be consistent: you won't have to open the header to know the member visibility - you just always know. this is also useful with templates.

遥远的她 2024-10-08 15:12:32

在这种情况下,您宁愿需要一个 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)< /code> 然后 fix_by 将调用 Mechanic.add_working_hour(0.5)。 XD

In this case you would rather need a Car.fix(const Mechanic&) function which then gives the engine to the Mechanic, say: Engine.fix(const Mechanic&), as I suppose the state of the Engine will be modified.

The original idea of using classes was to tie together the data with its accessor functions. If you do setter or getter which merely returns an internal data, it means that your data is not tied together with its accessor functionality: your class is not complete.

You want only to expose new data which a class emits. Say Car.get_exhaust() and the Car does not have the exhaust, only produces it, when you ask so. ;)

Or Fire Riefle.fire() whereas no access for Riefle::Trigger will be fixed by the mechanic like so: Trigger.fix_by(Mechanic) and then the fix_by will call say Mechanic.add_working_hour(0.5). XD

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文