簡體   English   中英

吸氣劑和二傳手風格

[英]getters and setters style

(暫不回答你應該擁有它們的問題。)

我一直希望只使用函數重載為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() );

當然我是對的,但我想知道圖書館作家是否有任何理由?

我更喜歡get / set版本,因為它更清楚了解發生了什么。 如果我看到rate()和rate(10),我怎么知道rate(10)不是簡單地在計算中使用10來返回率? 我沒有,所以現在我必須開始尋找弄清楚發生了什么。 單個函數名稱應該做一件事,而不是兩個相反的事情。

另外,正如其他人所指出的那樣,有些人更喜歡省略'get'並離開'set',即

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

這個慣例也很清楚,我讀這個也不會有任何問題。

我總是傾向於使用rate()而不是getRate()來省略getter上的'get'。 但是對於我而言,重載對於我來說似乎不是一個好主意,因為名稱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?

int rate();怎么樣int rate(); void setRate(int value); 這樣做的好處是不會有兩個同名的函數做不同的事情,並且仍然允許使用period() * rate()

幾年前,我完全同意了。 最近,一個疑問開始成為現實,因為這使得吸氣劑或制定者的地址變得模棱兩可。 使用像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));
);

撇開你應該擁有它們的問題;-)

我會繼續提及這應該是一個社區維基問題。

當我開始學習C ++時,我尋找樣式指南,谷歌對某些方面有好處:

  • 大寫的方法(它更漂亮)。
  • 明顯和低級( rate )。
  • setter顯式和小寫( setRate )。

簡潔是很重要的,但不能以不完整或誤導為代價。 出於這個原因,我更喜歡GetFoo()和SetFoo()到Foo()和Foo(int foo)。

“獲取”和“設置”有幾個級別

  • 我使用Get和Set進行“快速”操作。
  • 如果某些事情需要花費更長的時間來執行,那么它通常會是一個Calc,因為這些名稱意味着必須完成一些工作來檢索結果。
  • 對於更長的操作,您開始進入加載/保存,查詢/存儲,讀/寫,搜索/查找等前綴。

因此,Get / Set可以歸結為有用的含義,並且是更大,一致的命名策略的一部分。

沒有人提到的另一個問題是函數重載的情況。 拿這個(人為的和不完整的)例子:

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添加到我正在處理的項目的警告集中,並且看,這顯示在所有地方。

雖然Ed的評論是真的,但我確實更喜歡實際屬性而不是setter / getter反模式。 當域圖中1/3的方法是由eclipse生成的偽方法時,就會出現問題。

但是,如果沒有一流的屬性,我相信反模式最有意義。

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

obj.set (control shift space)
obj.get (control shift space)

就個人而言,我認為成對發現的吸氣劑和制定者是“視覺”語言及其“屬性”帶來的代碼味道。 在“好”類中,數據成員是writeonly或readonly但不是讀/寫。

我認為getter和setter最常見的原因是沒有足夠深入地攜帶對象模型。 在你的例子中,為什么總計通過了期間和費率? 他們不是班上的成員嗎? 所以你應該只設定期限和費率,你應該只得到一個總數。

可能有異常,但我只是討厭看一個類並找到“getX / setX,getY / setY等等”。 似乎沒有足夠的思考如何使用類,而是作者讓類EASY得到數據,所以他不必考慮如何使用類。

我當然是對的。

我強制執行一種方法,其中一個方法應該始終是一個動詞,一個類應該始終是一個名詞(出於顯而易見的原因除了仿函數)。 在這種情況下,必須使用get / set前綴來保持一致性。 也就是說,我也完全贊同Ed Swangren。 這總結給我使用這些前綴是一個明智的選擇。

我更喜歡避免使用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

如果你的getter只是rate() ,你的編譯器會抱怨它重新定義了你的其他rate符號,只要你給你的字段一個很好的有意義的名字就好了。 在這種情況下,你需要做一些愚蠢的事情,如命名你的成員_rate或其他類似的方法。 我個人討厭看/鍵入那些下划線,所以傾向於采用getRate()方法。

這顯然是主觀的,這恰好是我個人的偏好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM