• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            黎明的剔透里伸出了你沁清的曖昧

            Graphics|EngineDev|GameDev|2D&3D Art

              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              60 隨筆 :: 1 文章 :: 18 評論 :: 0 Trackbacks

            類型轉換操作符(type conversion operator)是一種特殊的類成員函數,它定義將類類型值轉變為其他類型值的轉換。轉換操作符在類定義體內聲明,在保留字 operator 之后跟著轉換的目標類型。boost::ref和boost::cref就使用到了類型轉換操作符。


            函數原型
            T1::operator T2() const;   //T1的成員函數,"(T2)a"類型轉換

            1. 轉換函數必須是成員函數,不能指定返回類型,并且形參表必須為空;返回值是隱含的,返回值是與轉換的類型相同的,即為上面原型中的T2;

            2. T2表示內置類型名(built-in type)、類類型名(class type)或由類型別名(typedef)定義的名字;對任何可作為函數返回類型的類型(除了 void 之外)都可以定義轉換函數,一般而言,不允許轉換為數組或函數類型,轉換為指針類型(數據和函數指針)以及引用類型是可以的;

            3. 轉換函數一般不應該改變被轉換的對象,因此轉換操作符通常應定義為 const 成員;

            4. 支持繼承,可以為虛函數;

            5. 只要存在轉換,編譯器將在可以使用內置轉換的地方自動調用它;


            for an example:
            #include <iostream>
            using namespace std;
            class D{
            public:
                D(
            double d):
                  d_(d){}
                  
            operator int()const{
                      cout
            <<"(int)d called!!"<<endl;
                      
            return static_cast<int>(d_);
                  }
            private:
                
            double d_;
            };

            int add(int a,int b){
                
            return a+b;
            }

            int main(){
                D d1
            =1.1;
                D d2
            =2.2;
                cout
            <<"add(d1,d2)="<<add(d1,d2)<<endl;
                
            return 0;
              
            }
            (int)d called!!
            (int)d called!!
            add(d1,d2)=3
            Press any key to continue

            類型轉換構造函數(conversion constructor)

            先來說下類型轉換構造函數:C++中的explicit用來修飾類的構造函數,表明該構造函數是顯示的,既然有顯示的,那么就有隱式的
            若果一個類的構造函數時一個單自變量的構造函數,所謂的單自變量是可能聲明一個單一參數,也可能聲明一個擁有多個參數,并且除了第一參數外都其他參數都有默認值
            這樣的constructor稱為單自變量constructor.
            若果類中有這樣一個constructor那么在編譯的時候編譯器將會產生一個省卻的操作:將該constructor參數對應 的 數據類型 的 數據轉換為該類的對象
            class MyClass
            {
            public:
            MyClass( int num );
            }
            ....
            MyClass obj = 10; //ok,convert int to MyClass

            在上面的操作中編譯器其實產生代碼如下:
            Myclass temp(10);
            Myclass obj=temp;

            若果要避免編譯器產生上訴的隱式轉換,那么此時explicit將產生作用。
            explicit的作用:
            explicit關鍵字將作用在類的構造函數,被修飾的構造函數,將再不能發生隱式轉換了,只能以顯示的進行類型轉換
            explicit 的注意:
            只能作用在類的內部的構造函數上
            只能作用在單自變量的構造函數上

            class Circle  {  
            public:  
               Circle(
            double r) : R(r) {}  
               Circle(
            int x, int y = 0) : X(x), Y(y) {}  
               Circle(
            const Circle& c) : R(c.R), X(c.X), Y(c.Y) {}  
            private:  
                
            double R;  
                
            int    X;  
                
            int    Y;  
            };    
            int main(){  
                       Circle A 
            = 1.23;   
                       
            //發生隱式類型轉換  
                       
            //編譯器會將它變成如下代碼  
                      
            //tmp = Circle(1.23)  
                      
            //Circle A(tmp);  
                      
            //tmp.~Circle();  

                      Circle B 
            = 123;  

                     
            //注意是int型的,調用的是Circle(int x, int y = 0)  
                    
            //它雖然有2個參數,但后一個有默認值,任然能發生隱式轉換
             
                      Circle C 
            = A;  
                     
            //這個算隱式調用了拷貝構造函數  

                    
            return 0;  




            加了explicit關鍵字后,可防止以上隱式類型轉換發生

             

             class Circle  {  
            public:  
                
            explicit Circle(double r) : R(r) {}  
                
            explicit Circle(int x, int y = 0) : X(x), Y(y) {}  
                
            explicit Circle(const Circle& c) : R(c.R), X(c.X), Y(c.Y) {}  
            private:  
               
            double R;  
               
            int    X;  
               
            int    Y;  
             };  
             
            int _main()  {  
                  
            //一下3句,都會報錯  
                  
            //Circle A = 1.23;   
                 
            //Circle B = 123;  
                 
            //Circle C = A;  
                   
                   
            //只能用顯示的方式調用了  
                  
            //未給拷貝構造函數加explicit之前可以這樣  
                    Circle A = Circle(1.23);  
                    Circle B 
            = Circle(123);  
                    Circle C 
            = A;  
             
                 
            //給拷貝構造函數加了explicit后只能這樣了  
                    Circle A(1.23);  
                    Circle B(
            123);  
                    Circle C(A);  

                    
            return 0;  


            類型轉換操作符 vs 類型轉換構造函數(conversion constructor)

            有時候使用conversion constructor就能實現類型轉換,這種方式效率更高而且也更直觀,下面舉例說明:

             

             

             1 #include <iostream>
             2 using namespace std;
             3 class A{
             4 public:
             5     A(int num=0)
             6         :dat(num){
             7         cout<<"A單參數構造函數called!!"<<endl;
             8     }
             9     operator int(){
            10        cout<<"A::operator int() called!!"<<endl;
            11        return dat;
            12     }
            13 private:
            14     int dat;
            15 };
            16 
            17 class X{
            18 public:
            19     X(int num=0)
            20         :dat(num){
            21     cout<<"X單參數構造函數called!!"<<endl;
            22     }
            23     operator int(){
            24         cout<<"X::operator int() called!!"<<endl;
            25         return dat;
            26     }
            27     operator A(){
            28         cout<<"operator    x() called!!"<<endl;
            29         A temp=dat;
            30         return temp;
            31     }
            32 private:
            33     int dat;
            34 };
            35 
            36 int main(){
            37     cout<<"///////trace more///////"<<endl;
            38     A more=0;
            39 
            40     cout<<"///////trace stuff///////"<<endl;
            41     X stuff=2;
            42 
            43     cout<<"//////trace hold dingyi////// "<<endl;
            44     int  hold;
            45 
            46      cout<<"///////trace hold=stuff//////"<<endl;
            47     hold=stuff;
            48     cout<<"///////two trace hold=stuff//////"<<endl;
            49     cout<<"hold:"<<hold<<endl;
            50 
            51     cout<<"//////trace more=stuff//////"<<endl;
            52     more =stuff;
            53     cout<<"//////two trace more=stuff//////"<<endl;
            54     cout<<"more:"<<more<<endl;
            55     
            56     return 0;
            57 }



            上面這個程序中X類通過“operator A()”類型轉換來實現將X類型對象轉換成A類型,這種方式需要先創建一個臨時A對象再用它去賦值目標對象;更好的方式是為A類增加一個構造函數:

             

            A(const X& rhs) : dat(rhs) {}

            同時,請注意上面程序的more的類型在調用std::cout時被隱式地轉成了int!

            一個簡單boost::ref實現

             

             

            通過重載type conversion operator,我們就可以自己實現一個簡版的boost::ref。

             

             1  #include <iostream>
             2  
             3  template <class T>
             4   class RefHolder{
             5   public:
             6      RefHolder(T& ref) : ref_(ref) {}
             7 
             8      /* “(T&)A”類型轉換操作符 */
             9      operator T& () const {
            10          return ref_;
            11      } 
            12 private:
            13       T& ref_;
            14 };
            15  
            16  
            17  template <class T>
            18  inline RefHolder<T> ByRef(T& t) {
            19      return RefHolder<T>(t);
            20  }
            21  
            22   int inc(int& num) {
            23      num++;
            24      return num;
            25  }
            26  
            27  
            28 int main() {
            29      int n = 1;
            30      std::cout << inc(ByRef(n)) << std::endl;    //RefHolder<int>被轉換成了"int&"類型
            31       
            32      return 0;
            33  }
            34   
            35 

             



            posted on 2012-01-07 00:33 情絕格調(fresmaster) 閱讀(3106) 評論(0)  編輯 收藏 引用 所屬分類: Coding
            亚洲午夜精品久久久久久浪潮 | 99久久777色| 精品久久久久久国产91| 精品久久久久久国产免费了| 亚洲国产成人久久一区WWW| AV无码久久久久不卡蜜桃| 91秦先生久久久久久久| 无码8090精品久久一区| 色欲综合久久中文字幕网| 久久精品免费大片国产大片| 久久久久亚洲精品天堂| 亚洲国产日韩欧美久久| 99久久无码一区人妻| 久久国产免费直播| 久久伊人五月天论坛| 久久青草国产精品一区| 久久久国产乱子伦精品作者 | 狠狠色丁香久久婷婷综合蜜芽五月| 亚洲av伊人久久综合密臀性色 | 亚洲欧美日韩精品久久亚洲区| 欧美午夜精品久久久久免费视| 久久精品一区二区影院| 亚洲国产精品久久久久久| 久久精品亚洲中文字幕无码麻豆| 久久综合亚洲色HEZYO国产| 99久久婷婷国产一区二区| 国产精品久久久久影院嫩草| 久久久久亚洲AV无码观看| 一本久久免费视频| 香蕉久久影院| 亚洲欧洲精品成人久久曰影片| 精品久久人人妻人人做精品 | 国产精品无码久久久久久| 久久ww精品w免费人成| 一本久久a久久精品vr综合| 2021最新久久久视精品爱| 久久亚洲精品无码观看不卡| 色偷偷88欧美精品久久久 | 亚洲伊人久久综合中文成人网| 人人狠狠综合88综合久久| 香蕉aa三级久久毛片|