2010-07-17 40 views
2

採取以下級和兩個對象定義:確實會向類的構造函數中添加一個虛擬參數來解決調用歧義,違反任何規則?

class Rect{ 
public: 
    enum centimeter; 
    enum meter; 
    Rect(double len,double wid,enum centimeter){ 
    length=(len/100); 
    width=(wid/100); 
    } 
    Rect(int len,int wid,enum meter){ 
    length=len; 
    width=wid; 
    } 
    //rest of implementation 
private: 
    double length;//in meters 
    double width;//in meters 
}; 
Rect obj1(10,5,Rect::centimeter()); 
Rect obj2(10,5,Rect::meter()); 

前兩個構造具有虛擬枚舉參數來調用解決造成這些僞參數是不存在的情況下,模糊性。儘管可能在這裏使用命名構造函數,但如果我堅持使用這些虛擬參數,是否違反了我應該注意的任何編碼規則?

+3

IMO,更簡潔的方法是將類的整個接口定義爲一個單元(即長度爲米),並要求該類的用戶自己進行轉換。 – 2010-07-17 18:55:50

+1

在構造函數體中設置成員(它們應該在* ctor-initializer-list *中初始化)是一個比額外參數更大的問題。 – 2010-07-17 21:01:21

回答

1

STL使用該成語來區分迭代器類型而不是概念。

+2

你能指出一個具體的例子嗎? – 2010-07-17 19:57:39

+2

@大衛:我認爲MSN是指那些常見的實現_internally_使用默認參數,像'的std ::爲了迭代器對和兩個'int'區分iterator_traits :: iterator_category'(如'的std ::向量 v (0,0);')。不過,我認爲std lib的一個更好的例子是'new(std :: nothrow)'。 – sbi 2010-07-17 21:16:07

10

我認爲這違反了我的品味。我會這樣編碼:

enum Unit { 
    Centimeter = 100, 
    Meter  = 1 
}; 

Rect(int len, int wid, Unit unit) { 
    length = len/(int) unit; 
    width = wid/(int) unit; 
} 

Rect obj1(10, 5, Rect::Centimeter); 
Rect obj2(10, 5, Rect::Meter); 
+1

@litb:你說得很好。但是當額外參數是一個類型時,通常可以做出編譯時決策(因爲它正在調用基於params類型的單獨構造函數)。當然這不是你不知道的);在這種情況下,我更喜歡你在這裏建議的方法,因爲它只是簡單地選擇單位。 – 2010-07-18 03:42:58

1

不能說這打破了一條規則,但是......這並不容易閱讀。

你爲什麼不能聲明

enum metrics { 
    centimeter, 
    meter 
}; 

,並用它作爲構造函數的參數?或者它可以是

class Rect { 
public: 
    static Rect CreateWithMeters(int width, int height); 
    static Rect CreateWithCentimenets(int width, int height); 
} 

要麼比現在的代碼更符合我的口味。

0
Rect(int len,int wid,enum centimeter){ 
    length=(len/100); 
    width=(wid/100); 
} 

除了別人寫的,這個邏輯是不好的,因爲Rect(99,99,Rect::centimeter())等於Rect(0,0,Rect::centimeter())

如果要存儲的內部平方米,不提供接口釐米,不是這樣,也沒有任何其他方式。

+0

我照顧它,不應該採取整數作爲具有釐米枚舉類型參數的構造函數的參數類型,將其更改爲雙倍。 – Pooria 2010-07-17 20:48:03

+0

沒有特別幫助,分數米還是丟棄。 – 2010-07-17 21:00:08

+0

您應該更改私有變量,否則它將無濟於事。當然,那麼你應該改變其他構造函數的一致性。 – zvone 2010-07-17 21:07:10

4

BOOST_STRONG_TYPEDEF可能是這裏的答案。

BOOST_STRONG_TYPEDEF(double, Meter) 
BOOST_STRONG_TYPEDEF(double, Centimeters) 
BOOST_STRONG_TYPEDEF(double, Furlongs) 

class Rect 
{ 
public: 
    Rect(Meter len, Meter wid) : length(len), width(wid) 
    {}; 

    Rect(Centimeter len, Centimeter wid) : length(len/100), width(wid/100) 
    {}; 
} 

Rect obj1(Meter(10),Meter(5)); 
Rect obj1(Centimeter(10),Centimeter(5)); 
相關問題