2010-11-06 27 views
6

有时我需要暴露一些类成员。例如在以下示例中,class Mechanic可能需要直接访问Engine组件。我已经多次读到所有字段都应该由mutator(accessor)方法访问,因为有几个原因。但是,有没有提供非const引用吸气时任何优势:提供非const引用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; 
} 

您还可以protected取代public如果你不喜欢这个例子。在现实生活中,当涉及到System.inSystem.out时,Java中有一些simlet。看起来,要完全符合某些人的说法,您需要拨打电话System.getInstance().getOut().println("hello world")。在这种情况下,除了许多官方代码外,我没有看到任何好处。

+0

没有近距离投票,但如果问题的目的是陈述一个理论,然后不同意所有与该理论相反的答案,那么它可能是“主观的和论证的”。无论你的理论是对还是错。 – 2010-11-13 03:07:57

+0

@Steve Jessop:不要这么热心,用投票排序问题,你会得到很多不准确的问题(问题不能是主观的,答案可以)。每个答案都或多或少是主观的。借口您的怀疑 - 我正在旅行,最近没有机会访问stackoverflow。 – doc 2010-11-13 11:44:14

+0

这就是为什么我不确定。如果有人真的在为某些事情寻找理由,我认为这很好,即使可能没有明确的理由。如果有人不相信有任何理由,但仍然要求理由,我认为“通常会导致对抗和争论”。这两种方式都没有造成严重伤害,但后者不是AFAIK网站的目的。 – 2010-11-13 12:18:24

回答

1

我发现合理的一点是提供这样的吸气剂。它使您的软件更容易集成(例如,当您想将接口翻译成另一种语言并绑定ABI时)。

3

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

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

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

}; // eo class Singleton 
+3

绝对downvoting单例模式。 – Puppy 2010-11-06 16:23:53

+2

啊,我记得Singleton模式全是风靡的时候......哎呀,我甚至记得PEEK和POKE都是风靡一时的。 :-) – Gorgen 2010-11-06 17:54:59

+4

是的,阵列是邪恶的,吸气剂和定型剂是邪恶的,单身是邪恶的,整个节目是邪恶的。最好的程序员是那些没有写一段代码的人。 +1,因为单身人士有时候很有用。 – doc 2010-11-06 21:33:06

0

对我来说是很有意义的位置:

提供吸气剂
image(i,j) = 234; 
1

一个优点是,当,如果你决定改变方式,吸气的作品,使用这个类的代码不需要重新编译。但是如果你有一个公共领域,然后决定做一个getter,所有的代码应该重新编译。除此之外,我没有看到任何让您的变量变为私有的严重的实际原因。但是请注意,只有当您必须为外部用户提供引用引擎的方式时,这一切才有效。如果可以设计软件以便完全消除这种需求,那会更好。

+1

如果您提供了一个字段,并且稍后更改为getter,则客户端代码不必重新编译,而必须重新编写。 – 2010-11-08 01:19:21

3

明确的获取者和设置者可以过度官僚;这取决于你的情况。

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

如果你的课程非常简单(例如接近POD)并且不太可能改变,那么它可能不值得实施getter和setter。

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

+1

为了更好的搜索,这被称为* encapsulation *。 – 2010-11-06 16:07:24

+1

我修正了这个例子。应该有两个版本的'engine()'方法:const和non-const。在我看来,有时候暴露成员和缩回封装很方便。 – doc 2010-11-06 16:13:10

0

不要考虑暴露类的私有成员,而应考虑更多地沿着这些类的调用方法的思路。 我读了一篇有趣的Java文章,Why Getter and Setter Methods are Evil,它适用于C++和Java一样。

+0

是的,我已阅读并撰写了题为“理论就是理论”的评论:)我的观点是,代码由操作和数据组成,而不仅仅是代码。不知怎的,你必须修改数据,所以文章显然是错误的。作者没有看到计算背后的大背景。他已经完成了一些构建在它上面的原理,称为面向对象编程(Object Oriented Programming)。但是,没有程序编程,OOP就不存在。 – doc 2010-11-06 16:25:39

+0

@doc:如果没用,为什么要担心理论上说什么呢?在计算机模式方面,理论并不是一些抽象的数学概念,有些白日梦想起来(阅读“首先设计模式”)。它们是出于需要而诞生的(由于实践中面临的问题)。你的问题是其中之一。所以当有人说“Getters and setters是邪恶的”时,它不像是说“1 == 1”。 – nakiya 2010-11-07 14:48:46

1

正如我最近接受的教育最近,吸气剂和二手设备的气味不好。但是,如果你想这样做,提供函数来获取和设置m_engine(由你定义),而不是仅仅暴露它(你没有干预)意味着你有一个插件点以备将来的变化。

+0

你怎么能实现,比如'class Window',它的宽度,高度以及其他一些没有getter和setters的属性?我们不会生气吗?大多数现实生活中的对象都像“class Window”一样;几乎普通的结构充满了一些方法。我以SFML库的形式满足了很少有accesors的设计(尽管'Window'有GetWidth或GetSize方法),因此我无法很好地扩展它的类。 – doc 2010-11-06 21:44:54

+0

我的答案有两点。首先是:封装很好。第二个是,如果你不能拥有第一个,那么获得者和接球者都很好。第二种情况下的想法是为了避免将来可能发生的代码重复(或者现在),如果你想对'Window'的宽度或高度执行一些约束。在第一点上,虽然安装者可以稍微放过一些,但为什么你需要获得者呢?这并不意味着你宁愿让吸气剂暴露在外面的那一点数据?如果它在课堂上,为什么让其他人篡改它(为什么甚至提供const getter)? – nakiya 2010-11-07 12:03:00

+0

在你的问题中,你应该做的是将一个'Mechanic'对象传递给'Car'对象,以便'Car'对象可以将'Engine'对象传递给'Mechanic'对象。这样,你消除了吸气剂,而'恐怖分子'将无法访问'汽车'的引擎。 – nakiya 2010-11-07 12:08:19

0

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

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

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

最后,你的代码将是一致的:你不会有打开标题以了解会员的知名度 - 你一直都知道。这对模板也很有用。

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