22、C++ Primer 4th 筆記,到類類型與從類類型的轉換

來源:互聯網
上載者:User

1、轉換分為到類類型與從類類型的轉換兩種。到類類型的轉換:通過轉換建構函式;從類類型的轉換:轉換操作符。

2、常用16個操作符:5個算術操作符(+、-、*、/、%)及其對應的複合賦值操作符,4 個關係操作符(<、<=、>、>=),以及相等操作符(==、!=)。

樣本

class SmallInt{public:SmallInt(int i = 0):val(i){//...}operator int() const {return val;} //轉換操作符函數,由SmallInt類類型轉換成int型。private:std::size_t val;};SmallInt si;double dval;si >= dval // si converted to int and then convert to doubleif (si) // si converted to int and then convert to bool

通用形式:operator type();

    type表示內建類型名,類類型名或由類型別名所定義的名字。對任何可作為函數傳回型別的類型(除了void之外),都可以定義轉換函式。一般而言,不允許轉換為數組或函數類型,轉換為指標類型(資料或函數指標)及引用是可以的。

轉換操作符函數必須及必須是成員函數,不能指定傳回型別,形參表必須為空白。

    類類型轉換不能傳遞(兩個都是自訂的轉換,而非內建類型的預設轉換),如A->B,B->C,但是我們不能把需要C型別參數的地方傳遞A類型的參數。

樣本

class SmallInt{public:SmallInt(int i = 0):val(i)  //(轉換)建構函式{//...}operator int() const {return val;} //轉換操作符函數,由SmallInt類類型轉換成int型。private:std::size_t val;};class Integral {public:Integral(int i = 0): val(i) { }operator SmallInt() const { return val % 256; }private:std::size_t val;};int calc(int);Integral intVal;SmallInt si(intVal); // ok: convert intVal to SmallInt and copy to siint i = calc(si); // ok: convert si to int and call calcint j = calc(intVal); // error: no conversion to int from Integral

3、完全符合轉換比需要標準轉換的其他轉換更好。

4、轉換的二義性

樣本二義性

#include "iostream"#include "vector"#include "algorithm"#include "string"#include "functional"using namespace std;class Integral;class SmallInt{public:SmallInt(Integral){}    //...};class Integral{public:operator SmallInt() const{}//...};void compute(SmallInt);int main(){Integral int_val;compute(int_val); //error:ambiguous}

避免二義性最好的方法是避免編寫互相提供隱式轉換的成對的類。保證最多隻有一種途經將一個類型轉換成另一個類型。

可以通過顯式強制消除二義性。

樣本

#include "iostream"#include "vector"#include "algorithm"#include "string"#include "functional"using namespace std;class SmallInt {public:// Conversions to int or double from SmallInt// Usually it is unwise to define conversions to multiple arithmetic typesoperator int() const { return val; }operator double() const { return val; }// ...private:std::size_t val;};void compute(int);void compute(double);void compute(long double);int main(){SmallInt si;//compute(si); // error: ambiguous//compute(static_cast<int>(si)); //ok, call compute(int)}

    有調用重載函數時,需要使用建構函式或強制類型轉換來轉換實參是拙劣設計的表現。

5、操作符的重載確定,三步:

1)選擇候選函數。

2)選擇可行函數,包括識別每個實參的潛在轉換序列。

3)選擇首選的函數。

6、幾個經驗

1)不要定義相互轉換的類,即如果類 Foo 具有接受類 Bar 的對象的建構函式,不要再為類 Bar 定義到類型 Foo 的轉換操作符。

2)避免到內建算術類型的轉換。具體而言,如果定義了到算術類型的轉換,則

    o不要定義接受算術類型的操作符的重載版本。如果使用者需要使用這些操作符,轉換操作符將轉換你所定義的類型的對象,然後可以使用內建操作符。

    o不要定義轉換到一個以上算術類型的轉換。讓標準轉換提供到其他算術類型的轉換。

    最簡單的規則是:對於那些“明顯正確”的,應避免定義轉換函式並限制非顯式建構函式。

參考

[1] http://blog.163.com/zhoumhan_0351/blog/static/3995422720103182106992/

[2] http://blog.163.com/zhoumhan_0351/blog/static/3995422720100284731826/

[3] http://blog.163.com/zhoumhan_0351/blog/static/3995422720104931348260/

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.