最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解C++中的轉(zhuǎn)換構(gòu)造函數(shù)

 更新時(shí)間:2023年09月20日 08:57:28   作者:向陽(yáng)逐夢(mèng)  
在 C/C++ 中,不同的數(shù)據(jù)類型之間可以相互轉(zhuǎn)換,無(wú)需用戶指明如何轉(zhuǎn)換的稱為自動(dòng)類型轉(zhuǎn)換(隱式類型轉(zhuǎn)換),需要用戶顯式地指明如何轉(zhuǎn)換的稱為強(qiáng)制類型轉(zhuǎn)換,本文就給大家詳細(xì)介紹一下C++的轉(zhuǎn)換構(gòu)造函數(shù),需要的朋友可以參考下

在 C/C++ 中,不同的數(shù)據(jù)類型之間可以相互轉(zhuǎn)換。無(wú)需用戶指明如何轉(zhuǎn)換的稱為自動(dòng)類型轉(zhuǎn)換(隱式類型轉(zhuǎn)換),需要用戶顯式地指明如何轉(zhuǎn)換的稱為強(qiáng)制類型轉(zhuǎn)換。

自動(dòng)類型轉(zhuǎn)換示例:

    int a = 6;
    a = 7.5 + a;

編譯器對(duì) 7.5 是作為 double 類型處理的,在求解表達(dá)式時(shí),先將 a 轉(zhuǎn)換為 double 類型,然后與 7.5 相加,得到和為 13.5。在向整型變量 a 賦值時(shí),將 13.5 轉(zhuǎn)換為整數(shù) 13,然后賦給 a。整個(gè)過(guò)程中,我們并沒(méi)有告訴編譯器如何去做,編譯器使用內(nèi)置的規(guī)則完成數(shù)據(jù)類型的轉(zhuǎn)換。強(qiáng)制類型轉(zhuǎn)換示例:

    int n = 100;
    int *p1 = &n;
    float *p2 = (float*)p1;

p1 是int *類型,它指向的內(nèi)存里面保存的是整數(shù),p2 是float *類型,將 p1 賦值給 p2 后,p2 也指向了這塊內(nèi)存,并把這塊內(nèi)存中的數(shù)據(jù)作為小數(shù)處理。我們知道,整數(shù)和小數(shù)的存儲(chǔ)格式大相徑庭,將整數(shù)作為小數(shù)處理非?;恼Q,可能會(huì)引發(fā)莫名其妙的錯(cuò)誤,所以編譯器默認(rèn)不允許將 p1 賦值給 p2。但是,使用強(qiáng)制類型轉(zhuǎn)換后,編譯器就認(rèn)為我們知道這種風(fēng)險(xiǎn)的存在,并進(jìn)行了適當(dāng)?shù)臋?quán)衡,所以最終還是允許了這種行為。

不管是自動(dòng)類型轉(zhuǎn)換還是強(qiáng)制類型轉(zhuǎn)換,前提必須是編譯器知道如何轉(zhuǎn)換,例如,將小數(shù)轉(zhuǎn)換為整數(shù)會(huì)抹掉小數(shù)點(diǎn)后面的數(shù)字,將int *轉(zhuǎn)換為float *只是簡(jiǎn)單地復(fù)制指針的值,這些規(guī)則都是編譯器內(nèi)置的,我們并沒(méi)有告訴編譯器。換句話說(shuō),如果編譯器不知道轉(zhuǎn)換規(guī)則就不能轉(zhuǎn)換,使用強(qiáng)制類型也無(wú)用,請(qǐng)看下面的例子:

    #include <iostream>
    using namespace std;
    //復(fù)數(shù)類
    class Complex{
    public:
        Complex(): m_real(0.0), m_imag(0.0){ }
        Complex(double real, double imag): m_real(real), m_imag(imag){ }
    public:
        friend ostream & operator<<(ostream &out, Complex &c);  //友元函數(shù)
    private:
        double m_real;  //實(shí)部
        double m_imag;  //虛部
    };
    //重載>>運(yùn)算符
    ostream & operator<<(ostream &out, Complex &c){
        out << c.m_real <<" + "<< c.m_imag <<"i";;
        return out;
    }
    int main(){
        Complex a(10.0, 20.0);
        a = (Complex)25.5;  //錯(cuò)誤,轉(zhuǎn)換失敗
        return 0;
    }

25.5 是實(shí)數(shù),a 是復(fù)數(shù),將 25.5 賦值給 a 后,我們期望 a 的實(shí)部變?yōu)?25.5,而虛部為 0。但是,編譯器并不知道這個(gè)轉(zhuǎn)換規(guī)則,這超出了編譯器的處理能力,所以轉(zhuǎn)換失敗,即使加上強(qiáng)制類型轉(zhuǎn)換也無(wú)用。

幸運(yùn)的是,C++ 允許我們自定義類型轉(zhuǎn)換規(guī)則,用戶可以將其它類型轉(zhuǎn)換為當(dāng)前類類型,也可以將當(dāng)前類類型轉(zhuǎn)換為其它類型。

這種自定義的類型轉(zhuǎn)換規(guī)則只能以類的成員函數(shù)的形式出現(xiàn),換句話說(shuō),這種轉(zhuǎn)換規(guī)則只適用于類。本節(jié)我們先講解如何將其它類型轉(zhuǎn)換為當(dāng)前類類型,下節(jié)再講解如何將當(dāng)前類類型轉(zhuǎn)換為其它類型。

轉(zhuǎn)換構(gòu)造函數(shù)

將其它類型轉(zhuǎn)換為當(dāng)前類類型需要借助轉(zhuǎn)換構(gòu)造函數(shù)(Conversion constructor)。轉(zhuǎn)換構(gòu)造函數(shù)也是一種構(gòu)造函數(shù),它遵循構(gòu)造函數(shù)的一般規(guī)則。轉(zhuǎn)換構(gòu)造函數(shù)只有一個(gè)參數(shù)。

仍然以 Complex 類為例,我們?yōu)樗砑愚D(zhuǎn)換構(gòu)造函數(shù):

    #include <iostream>
    using namespace std;
    //復(fù)數(shù)類
    class Complex{
    public:
        Complex(): m_real(0.0), m_imag(0.0){ }
        Complex(double real, double imag): m_real(real), m_imag(imag){ }
        Complex(double real): m_real(real), m_imag(0.0){ }  //轉(zhuǎn)換構(gòu)造函數(shù)
    public:
        friend ostream & operator<<(ostream &out, Complex &c);  //友元函數(shù)
    private:
        double m_real;  //實(shí)部
        double m_imag;  //虛部
    };
    //重載>>運(yùn)算符
    ostream & operator<<(ostream &out, Complex &c){
        out << c.m_real <<" + "<< c.m_imag <<"i";;
        return out;
    }
    int main(){
        Complex a(10.0, 20.0);
        cout<<a<<endl;
        a = 25.5;  //調(diào)用轉(zhuǎn)換構(gòu)造函數(shù)
        cout<<a<<endl;
        return 0;
    }

運(yùn)行結(jié)果:

10 + 20i

25.5 + 0i

Complex(double real);就是轉(zhuǎn)換構(gòu)造函數(shù),它的作用是將 double 類型的參數(shù) real 轉(zhuǎn)換成 Complex 類的對(duì)象,并將 real 作為復(fù)數(shù)的實(shí)部,將 0 作為復(fù)數(shù)的虛部。這樣一來(lái),a = 25.5;整體上的效果相當(dāng)于:

a.Complex(25.5);

將賦值的過(guò)程轉(zhuǎn)換成了函數(shù)調(diào)用的過(guò)程。在進(jìn)行數(shù)學(xué)運(yùn)算、賦值、拷貝等操作時(shí),如果遇到類型不兼容、需要將 double 類型轉(zhuǎn)換為 Complex 類型時(shí),編譯器會(huì)檢索當(dāng)前的類是否定義了轉(zhuǎn)換構(gòu)造函數(shù),如果沒(méi)有定義的話就轉(zhuǎn)換失敗,如果定義了的話就調(diào)用轉(zhuǎn)換構(gòu)造函數(shù)。

轉(zhuǎn)換構(gòu)造函數(shù)也是構(gòu)造函數(shù)的一種,它除了可以用來(lái)將其它類型轉(zhuǎn)換為當(dāng)前類類型,還可以用來(lái)初始化對(duì)象,這是構(gòu)造函數(shù)本來(lái)的意義。下面創(chuàng)建對(duì)象的方式是正確的:

    Complex c1(26.4);  //創(chuàng)建具名對(duì)象
    Complex c2 = 240.3;  //以拷貝的方式初始化對(duì)象
    Complex(15.9);  //創(chuàng)建匿名對(duì)象
    c1 = Complex(46.9);  //創(chuàng)建一個(gè)匿名對(duì)象并將它賦值給 c1

在以拷貝的方式初始化對(duì)象時(shí),編譯器先調(diào)用轉(zhuǎn)換構(gòu)造函數(shù),將 240.3 轉(zhuǎn)換為 Complex 類型(創(chuàng)建一個(gè) Complex 類的匿名對(duì)象),然后再拷貝給 c2。如果已經(jīng)對(duì)+運(yùn)算符進(jìn)行了重載,使之能進(jìn)行兩個(gè) Complex 類對(duì)象的相加,那么下面的語(yǔ)句也是正確的:

    Complex c1(15.6, 89.9);
    Complex c2;
    c2 = c1 + 29.6;
    cout<<c2<<endl;

在進(jìn)行加法運(yùn)算符時(shí),編譯器先將 29.6 轉(zhuǎn)換為 Complex 類型(創(chuàng)建一個(gè) Complex 類的匿名對(duì)象)再相加。需要注意的是,為了獲得目標(biāo)類型,編譯器會(huì)“不擇手段”,會(huì)綜合使用內(nèi)置的轉(zhuǎn)換規(guī)則和用戶自定義的轉(zhuǎn)換規(guī)則,并且會(huì)進(jìn)行多級(jí)類型轉(zhuǎn)換,例如:

  • 編譯器會(huì)根據(jù)內(nèi)置規(guī)則先將 int 轉(zhuǎn)換為 double,再根據(jù)用戶自定義規(guī)則將 double 轉(zhuǎn)換為 Complex(int --> double --> Complex);
  • 編譯器會(huì)根據(jù)內(nèi)置規(guī)則先將 char 轉(zhuǎn)換為 int,再將 int 轉(zhuǎn)換為 double,最后根據(jù)用戶自定義規(guī)則將 double 轉(zhuǎn)換為 Complex(char --> int --> double --> Complex)。

從本例看,只要一個(gè)類型能轉(zhuǎn)換為 double 類型,就能轉(zhuǎn)換為 Complex 類型。請(qǐng)看下面的例子:

    int main(){
        Complex c1 = 100;  //int --> double --> Complex
        cout<<c1<<endl;
        c1 = 'A';  //char --> int --> double --> Complex
        cout<<c1<<endl;
        c1 = true;  //bool --> int --> double --> Complex
        cout<<c1<<endl;
        Complex c2(25.8, 0.7);
        //假設(shè)已經(jīng)重載了+運(yùn)算符
        c1 = c2 + 'H' + true + 15;  //將char、bool、int都轉(zhuǎn)換為Complex類型再運(yùn)算
        cout<<c1<<endl;
        return 0;
    }

運(yùn)行結(jié)果:

100 + 0i

65 + 0i

1 + 0i

113.8 + 0.7i

再談構(gòu)造函數(shù)

構(gòu)造函數(shù)的本意是在創(chuàng)建對(duì)象的時(shí)候初始化對(duì)象,編譯器會(huì)根據(jù)傳遞的實(shí)參來(lái)匹配不同的(重載的)構(gòu)造函數(shù)?;仡櫼幌乱郧暗恼鹿?jié),到目前為止我們已經(jīng)學(xué)習(xí)了以下幾種構(gòu)造函數(shù)。

  • 默認(rèn)構(gòu)造函數(shù)。就是編譯器自動(dòng)生成的構(gòu)造函數(shù)。以 Complex 類為例,它的原型為:

Complex();  //沒(méi)有參數(shù)

  • 普通構(gòu)造函數(shù)。就是用戶自定義的構(gòu)造函數(shù)。以 Complex 類為例,它的原型為:

Complex(double real, double imag);  //兩個(gè)參數(shù)

  • 拷貝構(gòu)造函數(shù)。在以拷貝的方式初始化對(duì)象時(shí)調(diào)用。以 Complex 類為例,它的原型為:

Complex(const Complex &c);

  • 轉(zhuǎn)換構(gòu)造函數(shù)。將其它類型轉(zhuǎn)換為當(dāng)前類類型時(shí)調(diào)用。以 Complex 為例,它的原型為:

Complex(double real);

不管哪一種構(gòu)造函數(shù),都能夠用來(lái)初始化對(duì)象,這是構(gòu)造函數(shù)的本意。假設(shè) Complex 類定義了以上所有的構(gòu)造函數(shù),那么下面創(chuàng)建對(duì)象的方式都是正確的:

    Complex c1();  //調(diào)用Complex()
    Complex c2(10, 20);  //調(diào)用Complex(double real, double imag)
    Complex c3(c2);  //調(diào)用Complex(const Complex &c)
    Complex c4(25.7);  //調(diào)用Complex(double real)

這些代碼都體現(xiàn)了構(gòu)造函數(shù)的本意——在創(chuàng)建對(duì)象時(shí)初始化對(duì)象。除了在創(chuàng)建對(duì)象時(shí)初始化對(duì)象,其他情況下也會(huì)調(diào)用構(gòu)造函數(shù),例如,以拷貝的的方式初始化對(duì)象時(shí)會(huì)調(diào)用拷貝構(gòu)造函數(shù),將其它類型轉(zhuǎn)換為當(dāng)前類類型時(shí)會(huì)調(diào)用轉(zhuǎn)換構(gòu)造函數(shù)。這些在其他情況下調(diào)用的構(gòu)造函數(shù),就成了特殊的構(gòu)造函數(shù)了。特殊的構(gòu)造函數(shù)并不一定能體現(xiàn)出構(gòu)造函數(shù)的本意。

對(duì) Complex 類的進(jìn)一步精簡(jiǎn)

上面的 Complex 類中我們定義了三個(gè)構(gòu)造函數(shù),其中包括兩個(gè)普通的構(gòu)造函數(shù)和一個(gè)轉(zhuǎn)換構(gòu)造函數(shù)。其實(shí),借助函數(shù)的默認(rèn)參數(shù),我們可以將這三個(gè)構(gòu)造函數(shù)簡(jiǎn)化為一個(gè),請(qǐng)看下面的代碼:

    #include <iostream>
    using namespace std;
    //復(fù)數(shù)類
    class Complex{
    public:
        Complex(double real = 0.0, double imag = 0.0): m_real(real), m_imag(imag){ }
    public:
        friend ostream & operator<<(ostream &out, Complex &c);  //友元函數(shù)
    private:
        double m_real;  //實(shí)部
        double m_imag;  //虛部
    };
    //重載>>運(yùn)算符
    ostream & operator<<(ostream &out, Complex &c){
        out << c.m_real <<" + "<< c.m_imag <<"i";;
        return out;
    }
    int main(){
        Complex a(10.0, 20.0);  //向構(gòu)造函數(shù)傳遞 2 個(gè)實(shí)參,不使用默認(rèn)參數(shù)
        Complex b(89.5);  //向構(gòu)造函數(shù)傳遞 1 個(gè)實(shí)參,使用 1 個(gè)默認(rèn)參數(shù)
        Complex c;  //不向構(gòu)造函數(shù)傳遞實(shí)參,使用全部默認(rèn)參數(shù)
        a = 25.5;  //調(diào)用轉(zhuǎn)換構(gòu)造函數(shù)(向構(gòu)造函數(shù)傳遞 1 個(gè)實(shí)參,使用 1 個(gè)默認(rèn)參數(shù))
        return 0;
    }

精簡(jiǎn)后的構(gòu)造函數(shù)包含了兩個(gè)默認(rèn)參數(shù),在調(diào)用它時(shí)可以省略部分或者全部實(shí)參,也就是可以向它傳遞 0 個(gè)、1 個(gè)、2 個(gè)實(shí)參。轉(zhuǎn)換構(gòu)造函數(shù)就是包含了一個(gè)參數(shù)的構(gòu)造函數(shù),恰好能夠和其他兩個(gè)普通的構(gòu)造函數(shù)“融合”在一起。

以上就是一文詳解C++中的轉(zhuǎn)換構(gòu)造函數(shù)的詳細(xì)內(nèi)容,更多關(guān)于C++轉(zhuǎn)換構(gòu)造函數(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語(yǔ)言編程題楊氏矩陣算法快速上手示例詳解

    C語(yǔ)言編程題楊氏矩陣算法快速上手示例詳解

    這篇文章主要為大家介紹了C語(yǔ)言編程題楊氏矩陣算法快速上手的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-10-10
  • 函數(shù)式宏定義與普通函數(shù)的區(qū)別

    函數(shù)式宏定義與普通函數(shù)的區(qū)別

    盡管函數(shù)式宏定義和普通函數(shù)相比有很多缺點(diǎn),但只要小心使用還是會(huì)顯著提高代碼的執(zhí)行效率,畢竟省去了分配和釋放棧幀、傳參、傳返回值等一系列工作,因此那些簡(jiǎn)短并且被頻繁調(diào)用的函數(shù)經(jīng)常用函數(shù)式宏定義來(lái)代替實(shí)現(xiàn)
    2013-10-10
  • c++基礎(chǔ)學(xué)習(xí)之如何區(qū)分引用和指針

    c++基礎(chǔ)學(xué)習(xí)之如何區(qū)分引用和指針

    C語(yǔ)言中只有指針,C++加入了引用,能夠起到跟指針類似的作用,下面這篇文章主要給大家介紹了關(guān)于c++基礎(chǔ)學(xué)習(xí)之區(qū)分引用和指針的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-08-08
  • C++?的cout格式化輸出場(chǎng)景示例詳解

    C++?的cout格式化輸出場(chǎng)景示例詳解

    這篇文章主要為大家介紹了C++的cout格式化輸出場(chǎng)景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • C語(yǔ)言實(shí)現(xiàn)電話簿項(xiàng)目管理

    C語(yǔ)言實(shí)現(xiàn)電話簿項(xiàng)目管理

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)電話簿項(xiàng)目管理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C語(yǔ)言由淺入深了解變量的應(yīng)用

    C語(yǔ)言由淺入深了解變量的應(yīng)用

    這篇文章主要介紹了C語(yǔ)言的變量,變量是C語(yǔ)言語(yǔ)法和語(yǔ)義中一個(gè)很重要的知識(shí)點(diǎn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • C++實(shí)現(xiàn)單張圖片讀取和保存

    C++實(shí)現(xiàn)單張圖片讀取和保存

    這篇文章主要為大家詳細(xì)介紹了C++語(yǔ)言讀取和保存單張圖片的代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • C語(yǔ)言實(shí)現(xiàn)最大間隙問(wèn)題實(shí)例

    C語(yǔ)言實(shí)現(xiàn)最大間隙問(wèn)題實(shí)例

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)最大間隙問(wèn)題的方法,是一個(gè)比較經(jīng)典的算法設(shè)計(jì)問(wèn)題,對(duì)于學(xué)習(xí)算法設(shè)計(jì)有一定的借鑒價(jià)值,需要的朋友可以參考下
    2014-09-09
  • C++ const的各種用法詳解

    C++ const的各種用法詳解

    const名叫常量限定符,用來(lái)限定特定變量,以通知編譯器該變量是不可修改的。習(xí)慣性的使用const,可以避免在函數(shù)中對(duì)某些不應(yīng)修改的變量造成可能的改動(dòng)。本文主要談?wù)刢onst的用法,感興趣的同學(xué)可以參考閱讀
    2023-04-04
  • Java?C++?算法題解leetcode145商品折扣后最終價(jià)格單調(diào)棧

    Java?C++?算法題解leetcode145商品折扣后最終價(jià)格單調(diào)棧

    這篇文章主要介紹了Java?C++?算法題解leetcode145商品折扣后最終價(jià)格單調(diào)棧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09

最新評(píng)論

屏山县| 五指山市| 育儿| 香港| 石嘴山市| 车致| 镇江市| 平舆县| 大兴区| 景谷| 布拖县| 高陵县| 卓尼县| 余庆县| 库车县| 淮南市| 二连浩特市| 客服| 罗源县| 磐安县| 留坝县| 万载县| 牡丹江市| 阿拉善左旗| 承德县| 辉南县| 凌海市| 巴彦县| 阳高县| 改则县| 靖远县| 泸定县| 吉木萨尔县| 南城县| 河西区| 福建省| 万盛区| 潮安县| 宁河县| 闻喜县| 涟水县|