吸气剂和二传手风格

时间:2009-10-22 21:21:24

标签: c++ oop getter-setter

(撇开你应该拥有它们的问题。)

我一直希望只使用函数重载为getter和setter提供相同的名称。

int rate() { return _rate; }      
void rate(int value) { _rate = value; }

// instead of     
int getRate() { return _rate; }      
void setRate(int value) { _rate = value; }

// mainly because it allows me to write the much cleaner     
total( period() * rate() );    
// instead of      
setTotal( getPeriod() * getRate() );

当然我是对的,但我想知道图书馆作家是否有任何理由?

13 个答案:

答案 0 :(得分:32)

我更喜欢get / set版本,因为它更清楚发生了什么。如果我看到rate()和rate(10),我怎么知道rate(10)不是简单地在计算中使用10来返回率?我没有,所以现在我必须开始寻找弄清楚发生了什么。单个函数名称应该做一件事,而不是两个相反的事情。

另外,正如其他人所指出的那样,有些人宁愿省略'get'并留下'set',即

int Rate( );
void SetRate( int value );

这个惯例也很清楚,我读这个也不会有任何问题。

答案 1 :(得分:6)

我总是倾向于使用rate()而不是getRate()来省略吸毒者的“获取”。但是对于我来说,重载器对于我来说似乎不是一个好主意,因为名称rate并没有表明该对象正在被变异。考虑:

total(period() * rate()); // awesome, very clear

rate(20); // Looks like it computes a rate, using '20'...but for what?  And why ignore the return value?

答案 2 :(得分:6)

int rate();void setRate(int value);怎么样?这样做的好处是不会有两个同名的函数做不同的事情,并且仍然允许period() * rate()

答案 3 :(得分:5)

几年前,我完全同意了。最近,一个疑问开始成为现实,因为这使得吸气剂或制定者的地址变得模棱两可。使用像tr1 :: bind这样的工具,这真的很烦人。

例如:

struct A
{
   void Foo(int);
   int Foo()const;
};

std::vector<A> v = ....;
std::vector<int> foos;
// Extract Foo
std::transform(
   v.begin(), v.end(), 
   std::back_inserter(foos), 
   //Ambiguous
   // std::tr1::bind(&A::Foo)
   //must write this instead. Yuck!
   std::tr1::bind(static_cast<int(Foo::*)()>(&A::Foo));
);

撇开你应该拥有它们的问题; - )

答案 4 :(得分:4)

我会继续提及这应该是社区维基问题。

当我开始学习C ++时,我寻找风格指南,而谷歌对某些方面有好处:

  • 大写的方法(它更漂亮)。
  • 明白和低级(rate)。
  • 明确设置setter和小写(setRate)。

答案 5 :(得分:2)

简洁很重要,但不能以不完整或误导为代价。出于这个原因,我更喜欢GetFoo()和SetFoo()到Foo()和Foo(int foo)。

答案 6 :(得分:2)

“获取”和“设置”有几个级别

  • 我使用Get and Set进行“快速”操作。
  • 如果某些事情需要花费更长的时间来执行,那么它通常会是Calc,因为这些名称暗示必须完成一些工作来检索结果。
  • 对于较长时间的操作,您开始进入加载/保存,查询/存储,读/写,搜索/查找等前缀。

因此Get / Set可以归结为有用的含义,并且是更大,更一致的命名策略的一部分。

答案 7 :(得分:1)

虽然Ed的评论是真的,但我确实更喜欢setter / getter反模式的实际属性。域图中1/3的方法是由eclipse生成的虚拟方法时,就会出现问题。

但是,如果没有第一类属性,我相信反模式最有意义。

此外,它使代码完成更容易。

obj.set (control shift space)适用于制定者 获取者obj.get (control shift space)

答案 8 :(得分:1)

就我个人而言,我认为成对发现的吸气剂和制定者是“视觉”语言及其“属性”带来的代码味道。在“好”类中,数据成员是writeonly或readonly但不是读/写。

我认为getter和setter的最常见原因是没有足够深入地携带对象模型。在你的例子中,为什么总计通过了期间和费率?他们不是班上的成员吗?所以你应该只设定期限和费率,你应该只得到一个总数。

可能存在异常,但我只是讨厌看一个类并找到“getX / setX,getY / setY等等”。看起来似乎没有足够的思考如何使用类,而是作者让类EASY得到数据,所以他不必考虑如何使用类。

当然我是对的。

答案 9 :(得分:1)

没有其他人提到的另一个问题是函数重载的情况。拿这个(人为的和不完整的)例子:

class Employee {
    virtual int salary() { return salary_; }
    virtual void salary(int newSalary) { salary_ = newSalary; }
};

class Contractor : public Employee {
    virtual void salary(int newSalary) {
        validateSalaryCap(newSalary);
        Employee::salary(newSalary);
    }
    using Employee::salary; // Most developers will forget this
};

如果没有using子句,Contractor的用户由于超载而无法查询薪水。我最近将-Woverloaded-virtual添加到我正在处理的项目的警告集中,并且看,它出现在所有地方。

答案 10 :(得分:0)

我强制执行一种约定,其中一个方法应该始终是一个动词,一个类应该总是一个名词(出于显而易见的原因除了仿函数)。在这种情况下,必须使用get / set前缀来保持一致性。也就是说,我也完全赞同Ed Swangren。这总结给我使用这些前缀是一个明智的选择。

答案 11 :(得分:0)

我更喜欢避免使用get和set标签,编译器不需要这些信息来完成大多数这些简单属性的工作。

你可能有问题:

class Stuff {
  void widget( int something ); // 'special' setter
  const Widget& widget( int somethingelse ) const; // getter
}
Stuff a; 
a.widget(1); // compiler won't know which widget you mean, not enough info

答案 12 :(得分:0)

如果你的getter只是rate(),那么你的编译器会抱怨它重新定义了你的另一个rate符号,前提是你给了你的字段一个很有意义的名字。在这种情况下,您需要做一些愚蠢的事情,比如命名您的成员_rate或其他类似方法。我个人讨厌看到/输入那些下划线,所以倾向于采用getRate()方法。

这显然是主观的,这恰好是我个人的偏好。