2014-01-23 71 views
1

我必須用一個相當複雜的設置過程來構建一個時間跨度類。將會有幾個構造函數。在構造函數中調用setter是一個壞主意?我可以在構造函數中使用setter嗎?

我知道如果setter在派生類中被覆蓋,我不應該直接調用非私有setter來避免問題。我想過要麼創建一個真正的setter private幷包裝一個公共setter,並在構造函數中調用private setter以避免必須聲明它爲final。

class A { 
    public: 
     A(sometype data1, sometype data2); 

     void setData1(sometype data1); 
     void setData2(sometype data2); 

    private: 
     void p_setData1(sometype data1); 
     void p_setData2(sometype data2); 
}; 

A::A(sometype data1, sometype data2) { 
    p_setData1(data1); 
    p_setData2(data2); 
} 

void A::setData1(sometype data1) { p_setData1(data1); } 
void A::setData2(sometype data2) { p_setData2(data2); } 

void A::p_setData1(sometype data1) { 
    //Complex validation and calculations 
} 

void A::p_setData2(sometype data2) { 
    //Complex validation and calculations 
} 

有沒有人有最佳做法?

+4

我在構造函數中看不到使用setter的問題。您可以重複使用代碼,而不是在構造函數和setter中定義相同的setter邏輯。雖然我不確定爲什麼你有私人和公共製片人。如果他們是公開的,就讓他們公開。 – bblincoe

+1

注意:C++ 11帶來了構造函數的重用,例如,你可以使用'Foo(Radians r):Foo(r.toDegrees()){}'並且將所有構建邏輯委託給'Foo(Degrees d) ;'。注2:你的包裝器沒用,重要的不是你是否調用'public'或'private' setter,但是你是否在你的構造函數(或析構函數)中調用了一個**純虛擬**函數。 –

+2

'我知道如果setter在派生類中被覆蓋,我不應該直接調用非私有setter來避免問題。'沒有問題。該類的動態類型是ctor中的_this type_。 –

回答

6

關於

「我知道我不應該直接調用非私有制定者爲了避免出現問題,如果被二傳手在派生類中重寫。 」

這在很大程度上不是問題。即使使用虛擬設置器,構建類A時使用的定義也適用於動態類型A。 C++是安全的,與Java和C#相反(在基類不變式建立之前,您可能會冒險在派生類代碼中產生虛擬調用)。

關於最佳做法,它是對制定者和獲得者的批評。他們確實有自信的語言目的,例如, 「設計器」工具可以使用它們,但在C++中並不那麼多。所以,最好的做法是總是問,我是否真的需要他們,我可以設計一些其他方式(例如move而不是setxy(這可能聽起來不太一樣,但考慮從構造函數– move並沒有那麼多在施工期間感覺))。

+0

+1:所有部位都有Spot。 –

+0

在我的時間範疇類中,setters被反序列化方法主要使用,這些方法讀取大量不同的時間格式,並設置不同的成員變量,之後需要重新計算內部值。我不認爲有更好的方法來實現這一目標? – urzeit

2

在構造函數中調用setter是一個壞主意嗎?

否 - 在構造函數中使用setter允許您在setter方法和構造函數中重用setter邏輯,而無需對其進行定義。這意味着你只需要在一個地方而不是在setter和構造函數中進行修改。

相關問題