2011-08-04 27 views
7

我對C++比較陌生,我認爲我的問題可以通過示例來最好地理解。在我的頭文件,假設我有實現文件中的C++ Getters-Setters

class myClass{ 
    public: 
     double getVar1(); 
     void setVar1(double newVar1); 
     void copyVar1(myClass* dat); 

    private: 
     double var1; 
}; 

我在執行.cc文件,實現copyVar1方法時,應該怎麼辦

void myClass::copyVar1(myClass* dat){ 
    var1 = dat->var1; 
} 

void myClass::copyVar1(myClass* dat){ 
    var1 = dat->getVar1(); 
} 

其中第二情況下,我使用getter方法。在Visual C++中都可以正常工作,但我想知道在實踐中哪個更好。

謝謝您的意見!

+1

另請參閱[獲取和設置函數在C++程序員中流行](http://stackoverflow.com/questions/737409/are-get-and-set-functions-popular-with-c-programmers) –

回答

4

最佳做法?重載賦值運算符而不是編寫方法。

myClass & myClass::operator=(const myClass & dat) 
{ 
    var1 = dat.var1; // or dat.getVar1() 
    return *this; 
} 

至於使用該領域或調用setter ......這都是個人品味的問題。如果你的吸氣有副作用,那麼你可能應該叫它,否則,使用該領域。

所以,一個很大的「依賴」。

+1

但是,如果該類有不止一個成員,分配將不起作用,因爲它應該複製所有值,而不僅僅是一個。 – Skizz

+0

@Skizz的確,但這個例子只有一個領域。 –

+1

使用* getter *將操作集中到一個位置。這對維護和調試是有益的。編譯器應該足夠聰明以內聯getter;否則使內聯getter和setter來協助編譯器的優化。 –

0

這取決於。許多人會告訴你,使用getters/setter而不是變量對於編程錯誤和變化更加穩健,並且減少了代碼重複。但是,只要這些getter/setter沒有內聯函數,你可能會遇到很小的性能下降,因爲實現必須知道類的內部,爲什麼不直接使用這些變量。

1

我寧願使用setter方法和getter這樣,如果這樣你改變一些實現細節(例如引進價值分配確認)你開玩笑要改變的是,在二傳手一個地方...

+0

有時一個getter沒有匹配的成員變量,但以某種方式代替計算。在那些情況下,你顯然需要直接使用變量。沒有最終的答案imho:它總是取決於變量/吸氣劑代表什麼。 – ereOn

+0

@ereOn - 是取決於... –

0

你是不是想寫一個拷貝構造函數?爲什麼當你有setVar1時需要copyVar1?如果你想寫一個拷貝構造函數,最好不要使用getter。

myclass(const myclass& other) 
{ 
var1 = other.var1; 
} 

當你同時擁有getter和setter時,爲什麼不讓var1公開?

+0

在構造函數中使用初始化列表更好,而不是賦值。 –

+0

這只是一個簡單的例子。我目前已經實現了更多的copyVar1方法。 –

+0

@ A-A:那麼你想要的是**複製分配**。 'myclass&operator =(const myclass&other);'看看@Etienne解決方案。 – Mahesh

2

當你不在課堂上時,你應該幾乎總是使用getter/setter方法來訪問一個變量,並且通常你必須這樣做,因爲這是唯一的方法。但是,當你在類中時,你也可以使用它,如果getter方法什麼也不做,只是返回變量,它不會有什麼區別。

你的決定將是基於,如果你在,如果你想在copyVar1被稱爲可以運行該代碼,不會的東西不僅僅是返回變量多,getter方法有代碼。如果你不知道,我的建議是仍然使用getter方法,如果你決定在將來的代碼中使用更改。雖然現在只需直接訪問它,但它可以在顯微鏡下獲得更好的性能,但如果您不應該在應該調用時調用getter,則會更容易找到調用getter的錯誤。編譯器可能會最終優化到足以讓你甚至不會感覺到差異。 :D

+1

大多數編譯器都會內聯getter,因此性能不是問題。 –

0

在這裏沒有正確或錯誤的方法。

但是,您假定getVar1()返回值或var1。如果您決定更改var1值的存儲方式,則需要檢查所有代碼並進行更新。使用setter/getter可以將其減少爲幾種方法。在這種情況下,你應該使用第三個選項:

void myClass::copyVar1(myClass* dat){ 
    setVar1 (dat->getVar1()); 
} 

,然後你徹底清除VAR1的依賴,你可以改變VAR1別的東西和copyVar1仍然可以工作。

0

正如你所說,這兩個工作都正確並且完全合法。

從某種意義上講,直接訪問成員變量或使用訪問器的區別在於,在類中定義了更強的「層」此圖層與任何圖層一樣,可幫助您減少依賴關係。

換句話說,getter方法基本上響應了不向外界公開外部實現細節的要求;比如說,你可能會決定一天,而不是把var1作爲一個雙精度來存儲,你計算它。因此,訪問器爲您提供了這種自由:在一定程度上,您可以在不影響其他類的情況下更改實現(即減少依賴關係)。

在類本身中使用getter方法的情況下也是如此,例如,您正在刪除類範圍內的依賴關係,並且設計更易於更改。

0

setter和getters的抽象點在於檢索方法可能會改變。當你直接訪問成員變量時,如果有任何變化,你必須在任何地方更新你的用法。但是如果你使用這個函數,那麼改變檢索變量的方式只能在函數中改變。

現在,因爲這是同一個類,所以與將變量設爲公共時相比,這個問題要少得多,因爲您只需更新這一個實現文件(而不是更新您的類中的每個用戶,這可能不會如果你有一個圖書館課程是可能的)。

要看到這個,看看突然需要線程安全的類。現在,您的複印機看起來像

void myClass::copyVar1(myClass * dat) 
{ 
    scoped_lock lock(mutex); 
    var1 = dat->getVar1(); 
} 

如果您總是按功能調用,則無需在其他任何地方修復。如果你直接訪問的變量,那麼它看起來像

void myClass::copyVar1(myClass * dat) 
{ 
    scoped_lock lock(mutex); 
    scoped_lock lock2(dat->mutex) 
    var1 = dat->var1; 
} 

其鎖定「DAT」 S互斥體外部DAT,通常不被認爲是一個很好的設計(如果你讓工程師要記得鎖定其他人的對象那麼你開放了他們忘記的機會,而不是這樣做)。

同樣,如果變量開始存儲在數據庫中,您也必須處理該變量。或者,如果變量現在存儲在兩個不同的變量中,並在檢索時構建,您可以看到複雜度將如何增加。

但請記住,使用訪問器和增變器的設計理念是通過封裝降低潛在的複雜性。有些時候你不想改變班級的小型​​項目(特別是個人項目)。直接訪問它們可能並不複雜。不要害怕這樣做,只要知道你爲什麼做出這個決定。

+0

還要注意,你不應該使用複製構造函數或賦值操作符來作爲mutators - 它們應該在不同的地方使用。複製和分配用於當你想擁有一個你想要的另一個對象時。當您希望能夠以某種特定方式修改行爲而不修改對象的其餘部分時使用Mutators。如果有其他狀態不會改變,你只寫增變器。你的mutator的形式(它需要來自另一個現有對象的狀態)不應該暗示它必須是一個賦值或複製。 – ex0du5