2011-12-10 43 views
8

所以,我有一個考試的一天,和其中一個問題是非常類似於這樣:重載static_cast?

我們有一個叫做Square持有可變int side類。我們如何才能使cout << static_cast<int>(aSquare) <<endl;打印aSquare的區域?

這可能嗎?

回答

18

可以做這項工作,但不能通過超載static_cast<>()。您可以通過重載類型轉換操作符這樣做:

class Square 
{ 
public: 
    Square(int side) : side(side) {} 
    operator int() const { return side * side; } // overloaded typecast operator 
private: 
    int side; 
}; 

// ... 

// Compiler calls Square::operator int() to convert aSquare into an int 
cout << static_cast<int>(aSquare) <<endl; 

要注意的是重載類型轉換運營商往往不是傾向於做弊大於利。他們使很多無意義的隱式投射操作成爲可能。當您閱讀下面的代碼片段時,您是否認爲「a會獲得s的區域」?

Square aSquare; 
int a = aSquare; // What the heck does this do? 

我當然沒有。這使得更多的方式和感覺是更可讀:

Square aSquare; 
int a = aSquare.GetArea(); 

且不說通常要能夠訪問有關Square其他信息,如GetSide()GetApothem()GetPerimeter()或什麼的。 operator int()顯然只能返回一個int,並且不能有多個operator int()作爲類的成員。

這裏是另一種情況,其中operator int()使得代碼,編譯又是沒有任何意義:

Square s; 
if(s > 42) {} // Huh?! 

是什麼意思爲Square比42還大嗎?這是無稽之談,但operator int()上面的代碼將編譯爲Shape現在可以轉換爲int,它可以與另一個int與值4比較。

所以不要寫這樣的類型轉換運算符。事實上,如果你重載了類型轉換運算符,你可能想要考慮一下你正在做什麼。實際上只有少數情況下,在現代C++中重載類型轉換運算符是有用的(例如the safe bool idiom)。

+0

+1:Square類可以使用更多的方法,例如'GetSideLength()const','int GetPerimeter()const',這是爲了消除對GetArea()使用命名方法的歧義。 – rwong

+0

感謝您的精心解答。 – Radix

+2

@In silico:使用C++ 11,安全的bool習語不再是必需的,因爲C++ 11支持轉換操作符的關鍵字'explicit'。 – smerlin

1

你可以爲Square類提供了一個轉換操作符:

class Square 
{ 
public: 
    operator int() 
    { 
     return side * side; 
    } 
private: 
    int side; 
}; 
+0

它應該返回該區域,而不是一側 – Dani

+2

對於非常小的正方形實例適用。 –

+2

@Dani:我想你錯過了這一點。我相信OP知道如何計算面積。這個問題正確地回答瞭如何從方形對象中獲得一個int,這是問題的技術部分。 –

4

可以重載轉換運算符:

struct square { 
    operator int() const { 
    return (side * side); 
    } 
    int side; 
}; 

唯一的問題是,它會被隱式使用,鑄造沒有按這裏沒什麼意義。

struct square { 
    int get_area() const { 
    return (side * side); 
    } 
    int side; 
} 

如果必須使用強制轉換,使用C:你也不能在不同類型的類型轉換(的static_cast,C風格等)

這是做事的首選方式區分++ 11功能並將其標記爲explicit。這可以防止隱含的鑄造錯誤。