<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 一.轉換函數的類型 1. 轉換構造函數:從其他類型到類類型 `T` 2. 類型轉換函數:從類類型 `T` 到其他類型 ## 二.轉換構造函數 ### 1.工作 它的主要工作是構造對象,順帶完成類型轉換工作。 ### 2.調用方式 **既可以被編譯器自動調用,也可以被用戶強制調用。** ### 3.定義和聲明 + 轉換構造函數是構造函數中的一種,其定義和聲明與構造函數是一樣的。 + 轉換構造函數在調用時只會傳入一個參數,因此應該保證 **轉換構造函數至少有一個形參,且最多只有一個形參沒有默認參數** 。 #### 例1 下面是一個帶有轉換構造函數的類 `Complex` 。 ```c++ class Complex { private: double real_; double imaginary_; public: Complex() : real_(0), imaginary_(0) { } //轉換構造函數 Complex(double real) : real_(real), imaginary_(0) { } Complex(double real, double imaginary) : real_(real), imaginary_(imaginary) { } Complex &set_real(double new_val) { this->real_ = new_val; return *this; } Complex &set_imaginary(double new_val) { this->imaginary_ = new_val; return *this; } }; ``` 然后,就可以這么創建對象: ```c Complex a,b = 6,c(6,5); ``` 接下來,我們來簡化構造函數: ```c++ class Complex { private: double real_; double imaginary_; public: Complex() : real_(0), imaginary_(0) { } //既是轉換構造函數,也是普通構造函數 Complex(double real, double imaginary = 0) : real_(real), imaginary_(imaginary) { } Complex &set_real(double new_val) { this->real_ = new_val; return *this; } Complex &set_imaginary(double new_val) { this->imaginary_ = new_val; return *this; } }; ``` 然后依然可以這么調用: ```c Complex a,b = 6,c(6,5); ``` 最后我們進一步簡化構造函數: ```c class Complex { private: double real_; double imaginary_; public: //缺省構造函數,轉換構造函數,普通構造函數 Complex(double real = 0, double imaginary = 0) : real_(real), imaginary_(imaginary) { } Complex &set_real(double new_val) { this->real_ = new_val; return *this; } Complex &set_imaginary(double new_val) { this->imaginary_ = new_val; return *this; } }; ``` 照樣可以這樣調用: ```c Complex a,b = 6,c(6,5); ``` ## 三.類型轉換函數 ### 1.調用方式 **既可以被編譯器自動調用,也可以被用戶強制調用。** ### 2.定義和聲明 + 類似于重載強制類型轉換運算符。 + 只能 **在類內重載** 。因為轉換的主體是對象本身。 + 沒有參數。因為調用時第一個參數為對象本身。 >[warning] 由于類型轉換函數只能被編譯器自動調用,它不允許添加默認參數。 + 不可指定返回類型。但它有返回類型。 #### 例2 下面是一個帶有類型轉換函數的類 `Complex` 。 ```c++ class Complex { private: double real_; double imaginary_; public: Complex() : real_(0), imaginary_(0) {} Complex(double real, double imaginary) : real_(real), imaginary_(imaginary) {} Complex &set_real(double new_val) { this->real_ = new_val; return *this; } Complex &set_imaginary(double new_val) { this->imaginary_ = new_val; return *this; } //類型轉換函數 operator double() { return this->real_; } }; ``` 然后就可以把 `Complex` 對象賦值給 `double` 型變量: ```c++ double d = Complex(6,5); ``` ## 四.類型轉換與二義性 1. 不要令兩個類執行相同的類型轉換:如果 `A` 類有一個接受 `B` 類對象的構造函數,則不要在 `B` 類中再定義轉換目標是 `A` 類的類型轉換運算符。 2. 避免定義 `A` 與 `B` 的雙向轉換,特別是同時重載了雙目運算符。 3. 避免轉換目標是內置算術類型的類型轉換,特別是當你已經定義了一個轉換成算術類型的類型轉換時: + 不要再定義接受算術類型的重載運算符。如果用戶需要使用這樣的運算符,則類型轉換操作將轉換你的類型的對象,然后使用內置的運算符。 + 不要定義轉換到多種算術類型的類型轉換。讓標準類型轉換完成向其他算術類型轉換的工作。 ### 1.同一轉換起終點,多種轉換路徑 如果類中包含一個或多個類型轉換,則必須確保在類類型和目標類型之間只存在唯一一種轉換方式。 否則的話,我們編寫的代碼將很可能會具有二義性。 #### 例3 假設有以下類的聲明和函數: ```c++ struct B; struct A { int a; A(){} A(B &b){} }; struct B { int b; B(){}; operator A(){}; }; A f(const A &a) { return a; } ``` 從上面代碼中可以看到,有兩種從B到A的轉換函數。因此,下面的代碼運行時會出現二義性: ```c++ B b; f(b);//Ambiguous user-defined-conversion ``` ### 2.同時定義多個內置類型與類類型的轉換 #### 例4 假設有以下類的聲明和函數: ```c++ struct A { int a; A(){} operator double() {return 0;} operator int() {return 0;} }; void f(long double ld) { } ``` 若執行下面代碼,則會出現二義性: ```c++ A a; f(a);//Ambiguous user-defined-conversion ``` 在對 `f` 的調用中,哪個參數類型都無法精確匹配 `long double` .然而只要后面再執行一次到 `long double` 的轉換即可。因此,在上面的兩個類型轉換中兩個都差不多,調用將產生二義性。 ![](https://img.kancloud.cn/ac/42/ac4246368592a713057f1ae2c0f9df28_922x315.png) #### 例5 假設有以下類的聲明: ```c++ struct A { int a; A(double a) {} A(int a) {} }; ``` 若執行下面代碼,則不會出現二義性: ```c++ short b = 3; A a(b); ``` 為什么呢?在對構造函數的調用中,哪個參數類型都無法精確匹配 `short`。但是把 `short` 提升成 `int` 的操作優于把 `short` 轉換成 `double` 的操作,因此匹配 `A(int a)` 。(注:類型提升優于其他算術轉換,詳情參考 *面向過程編程.函數.函數重載* ) ![](https://img.kancloud.cn/82/7c/827c79cc61b1c2f5be38b0b2f04a1dba_616x319.png) 盡管這個例子沒有引起二義性,但實際運用中這樣寫容易出現錯誤。 ### 3.重載函數與轉換構造函數 #### 例6 假設有以下類的聲明和函數定義: ```c++ struct A { int a; A(int i) {} }; struct B { int b; B(int i) {} }; void overload(const A &a){} void overload(const B &b){} ``` 那么,當我們這樣調用 `overload` 時,出現了二義性: ```c++ overload(10);//ambiguous call to overloaded function ``` 因為這樣調用 `overload` 函數時,有下面兩種匹配方式,而且差別也不大: ![](https://img.kancloud.cn/de/73/de73d20e92fee7dce465bf9298ef05c7_861x324.png) ### 4.重載函數與用戶定義的轉換 當調用重載函數時,如果多個用戶定義的類型轉換都提供了可行匹配,則我們認為 **這些類型轉換優先級相同** 。 在這個過程中,我們不會考慮任何可能出現的標準類型轉換的級別。只有當重載函數能通過同名類型轉換函數得到匹配時,我們才會考慮其中出現的標準類型轉換。 #### 例7 假設有以下類的聲明和函數定義: ```c++ struct A { int a; A(int i) {} }; struct B { int b; B(double i) {} }; void overload(const A &a){} void overload(const B &b){} ``` 那么,當我們這樣調用 `overload` 時,依然會出現二義性: ```c++ overload(10);//ambiguous call to overloaded function ``` 盡管在 `B` 中,匹配的函數中間需要將 `int` 轉換成 `double` ,但是編譯器仍認為 `A(int)` 和 `B(double)` 是差不多的匹配。 ![](https://img.kancloud.cn/66/53/66536c5c18411a90f9b01a54aae49446_883x311.png) ### 5.雙向轉換與二義性 #### 例8 假設有以下定義和聲明: ```c++ class Complex { private: double real_; double imaginary_; public: Complex() : real_(0), imaginary_(0) {} //包括一個double 到 Complex 的轉換 Complex(double real, double imaginary = 0) : real_(real), imaginary_(imaginary) {} //Complex 到 double 的轉換 operator double() const { return this->real_; } //加法運算友元函數 friend Complex operator+(const Complex& c1,const Complex& c2); }; Complex operator+(const Complex& c1,const Complex& c2) { return Complex(c1.real_ + c2.real_,c1.imaginary_ + c2.imaginary_); } ``` 接下來用 `Complex` 定義兩個對象: ```c++ Complex c1(1,2),c2(3,4); ``` 下面的運算沒有任何問題: ```c++ c1+c2; ``` 但是接下來的運算便有了二義性: ```c++ c1+2.5;//2 overloads have similar conversions ``` ![](https://img.kancloud.cn/de/d0/ded005bd0ce128fdeea04ca3b74851f8_614x349.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看