2010-11-06 47 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