• <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>
            隨筆 - 30, 文章 - 0, 評論 - 64, 引用 - 0
            數(shù)據(jù)加載中……

            類型轉(zhuǎn)換高級 (Advacned Class Type-casting)

            reinterpret_cast

            reinterpret_cast 可以將一個指針轉(zhuǎn)換為任意其它類型的指針。
            它也可以用來將一個指針轉(zhuǎn)換為一個整型,或反之亦然。

            這個操作符可以在互不相關(guān)的類之間進行指針轉(zhuǎn)換,
            操作的結(jié)果是簡單的將一個指針的二進制數(shù)據(jù)(binary copy)復(fù)制到另一個指針。
            對指針指向的內(nèi)容不做任何檢查或轉(zhuǎn)換。

            例如:

            class A {};
            class B {};
            A * a = new A;
            B * b = reinterpret_cast<B*>(a);

            reinterpret_cast 對所有指針的處理與傳統(tǒng)的類型轉(zhuǎn)換符所作的一模一樣。

            _________________________________________________________________

            static_cast

            static_cast 可以執(zhí)行所有能夠隱含執(zhí)行的類型轉(zhuǎn)換,以及它們的反向操作(即使這種方向操作是不允許隱含執(zhí)行的)。

            用于類的指針,也就是說,它允許將一個引申類的指針轉(zhuǎn)換為其基類類型(這是可以被隱含執(zhí)行的有效轉(zhuǎn)換),同時也允許進行相反的轉(zhuǎn)換:將一個基類轉(zhuǎn)換為一個引申類類型。

            在后面一種情況中,不會檢查被轉(zhuǎn)換的基類是否真正完全是目標類型的。例如下面的代碼是合法的:

            class Base {};
            class Derived: public Base {};
            Base * a = new Base;
            Derived * b = static_cast(a);

            static_cast除了能夠?qū)︻愔羔樳M行操作,還可以被用來進行類中明確定義的轉(zhuǎn)換,以及對基本類型的標準轉(zhuǎn)換:

            double d=3.14159265;
            int i = static_cast<int>(d);

            譯者注:如果你對這部分看不太懂,請結(jié)合下面的dynamic_cast一起看,也許會幫助理解。











            dynamic_cast

            dynamic_cast 完全被用來進行指針的操作。它可以用來進行任何可以隱含進行的轉(zhuǎn)換操作以及它們被用于多態(tài)類情況下的方向操作。

            然而與static_cast不同的是,
             dynamic_cast 會檢查后一種情況的操作是否合法,
            也就是說它會檢查類型轉(zhuǎn)換操作是否會返回一個被要求類型的有效的完整的對象。

            這種檢查是在程序運行過程中進行的。如果被轉(zhuǎn)換的指針所指向的對象不是一個被要求類型的有效完整的對象,返回值將會是一個空指針NULL 。

               class Base { virtual dummy(){}; };
            class Derived : public Base { };


            Base* b1 = new Derived;
            Base* b2 = new Base;
            Derived* d1 = dynamic_cast(b1); // succeeds Derived* d2 = dynamic_cast(b2); // fails: returns NULL

            如果類型轉(zhuǎn)換被用在引用(reference)類型上,而這個轉(zhuǎn)換不可能進行的話,一個bad_cast 類型的例外(exception)將會被拋出:

              class Base { virtual dummy(){}; };
            class Derived : public Base { };

            Base* b1 = new Derived;
            Base* b2 = new Base;
            Derived d1 = dynamic_cast(b1); // succeeds Derived d2 = dynamic_cast(b2); // fails: exception thrown








            const_cast

            這種類型轉(zhuǎn)換對常量const 進行設(shè)置或取消操作:

            class C {};
            const C * a = new C;
            C * b = const_cast<C*> (a);

            其他3種cast 操作符都不可以修改一個對象的常量屬性(constness)。




            typeid

            ANSI-C++ 還定義了一個新的操作符叫做 typeid ,
            它檢查一個表達式的類型:

            typeid (expression)

            這個操作符返回一個類型為type_info的常量對象指針,這種類型定義在標準頭函數(shù)中。這種返回值可以用操作符 == 和 != 來互相進行比較,
            也可以用來通過name()函數(shù)獲得一個描述數(shù)據(jù)類型或類名稱的字符串,

            例如:

                // typeid, typeinfo
                        #include <iostream.h>
                        #include <typeinfo>
                        class CDummy { };
                        int main () {
                        CDummy* a,b;
                        if (typeid(a) != typeid(b)) {
                        cout << "a and b are of different types:\n";
                        cout << "a is: " << typeid(a).name() << '\n';
                        cout << "b is: " << typeid(b).name() << '\n';
                        }
                        return 0;
                        }
                        
            a and b are of different types:
            a is: class CDummy *
            b is: class CDummy


            posted @ 2008-12-08 12:58 henry08 閱讀(483) | 評論 (0)編輯 收藏

            名空間 (Namespaces)

            標準名空間(Namespace std)


             

            我們能夠找到的關(guān)于名空間的最好的例子就是標準C++ 函數(shù)庫本身。

            如ANSI C++ 標準定義,
            標準C++庫中的所有類、對象和函數(shù)都是定義在名空間std下面的。

            你可能已經(jīng)注意到,我們在這個教程中全部忽略了這一點。作者決定這么做是因為這條規(guī)則幾乎和ANSI 標準本身一樣年輕 (1997) ,許多老一點的編譯器并不兼容這條規(guī)則。

            幾乎所有的編譯器,即使是那些與ANSI 標準兼容的編譯器,都允許使用傳統(tǒng)的頭文件 (如iostream.h, stdlib.h, 等等),就像我們在這個教程中所使用的一樣。


            然而,ANSI標準完全重新設(shè)計了這些函數(shù)庫,
            利用了模板功能,
            而且遵循了這條規(guī)則將所有的函數(shù)和變量定義在了名空間std下。

            該標準為這些頭文件定義了新的名字,對針對C++的文件基本上是使用同樣的名字,但沒有.h的擴展名,

            例如, iostream.h 變成了iostream。

            如果我們使用ANSI-C++ 兼容的包含文件,我們必須記住所有的函數(shù)、類和對象是定義在名空間 std 下面的,例如:

                // ANSI-C++ compliant hello world
                        #include <iostream>
                        int main () {
                        std::cout << "Hello world in ANSI-C++\n";
            return 0;
            }
            Hello world in ANSI-C++

            更常用的方法是使用using namespace ,這樣我們就不必在所有標準空間中定義的函數(shù)或?qū)ο笄懊婵偸鞘褂梅秶僮鞣?:了 :

                // ANSI-C++ compliant hello world (II)
                        #include <iostream>
                        using namespace std;
                        int main () {
                        cout << "Hello world in ANSI-C++\n";
                        return 0;
                        }
                        
            Hello world in ANSI-C++

            對于STL 用戶,強烈建議使用ANSI-compliant 方式來包含標準函數(shù)庫。

            posted @ 2008-12-08 12:33 henry08 閱讀(378) | 評論 (0)編輯 收藏

            模板與多文件工程

            template <class T> // 最常用的:一個class 參數(shù)。

            template <class T, class U> // 兩個class 參數(shù)。

            template <class T, int N> // 一個class 和一個整數(shù)。

            template <class T = char> // 有一個默認值。

            template <int Tfunc (int)> // 參數(shù)為一個函數(shù)。

            從編譯器的角度來看,模板不同于一般的函數(shù)或類。
            它們在需要時才被編譯(compiled on demand),
            也就是說一個模板的代碼直到需要生成一個對象的時候(instantiation)才被編譯。
            當需要instantiation的時候,編譯器根據(jù)模板為特定的調(diào)用數(shù)據(jù)類型生成一個特殊的函數(shù)。


            當工程變得越來越大的時候,程序代碼通常會被分割為多個源程序文件。
            在這種情況下,通常接口(interface)和實現(xiàn)(implementation)是分開的。


            用一個函數(shù)庫做例子
                 接口通常包括所有能被調(diào)用的函數(shù)的原型定義。
                                                它們通常被定義在以.h 為擴展名的頭文件 (header file) 中;
                  而實現(xiàn) (函數(shù)的定義) 
                                                則在獨立的C++代碼文件中。


            模板這種類似宏(macro-like) 的功能,對多文件工程有一定的限制:
            函數(shù)或類模板的實現(xiàn) (定義) 必須與原型聲明在同一個文件中
            也就是說我們不能再 將接口(interface)存儲在單獨的頭文件中,
            而必須將接口和實現(xiàn)放在使用模板的同一個文件中。

            回到函數(shù)庫的例子,如果我們想要建立一個函數(shù)模板的庫,我們不能再使用頭文件(.h) ,取而代之,我們應(yīng)該生成一個模板文件(template file),將函數(shù)模板的接口和實現(xiàn) 都放在這個文件中 (這種文件沒有慣用擴展名,除了不要使用.h擴展名或不要不加任何擴展名)。


            在一個工程中多次包含同時具有聲明和實現(xiàn)的模板文件并不會產(chǎn)生鏈接錯誤 (linkage errors),因為它們只有在需要時才被編譯,而兼容模板的編譯器應(yīng)該已經(jīng)考慮到這種情況,不會生成重復(fù)的代碼。

            posted @ 2008-12-08 12:03 henry08 閱讀(474) | 評論 (0)編輯 收藏

            靜態(tài)成員(Static members)

            靜態(tài)成員與全域變量(global variable)具有相同的屬性,但它享有類(class)的范圍




            C++ 標準,為了避免它們被多次重復(fù)聲明,
            在class的聲明中只能夠包括static member的原型(聲明),
            而不能夠包括其定義(初始化操作)。
            為了初始化一個靜態(tài)數(shù)據(jù)成員,
            我們必須在class之外(在全域范圍內(nèi)),
            包括一個正式的定義,就像上面例子中做法一樣。





            在提醒一次,它其實是一個全域變量。唯一的不同是它的名字跟在class的后面。

            就像我們會在class中包含static數(shù)據(jù)一樣,我們也可以使它包含static 函數(shù)。
            它們表示相同的含義:static函數(shù)是全域函數(shù)(global functions),但是像一個指定class的對象成員一樣被調(diào)用。
            它們只能夠引用static 數(shù)據(jù),永遠不能引用class的非靜態(tài)(nonstatic)成員。
            它們也不能夠使用關(guān)鍵字this,因為this實際引用了一個對象指針,
            但這些 static函數(shù)卻不是任何object的成員,而是class的直接成員。

            posted @ 2008-12-04 18:34 henry08 閱讀(354) | 評論 (0)編輯 收藏

            定義一個class而沒有明確定義構(gòu)造函數(shù)的時候,編譯器會自動假設(shè)兩個重載的構(gòu)造函數(shù)

            實際上,當我們定義一個class而沒有明確定義構(gòu)造函數(shù)的時候,


            編譯器會自動假設(shè)兩個重載的構(gòu)造函數(shù)
             (默認構(gòu)造函數(shù)"default constructor" 和復(fù)制構(gòu)造函數(shù)"copy constructor")。


            例如,對以下class:

               class CExample {
            public:
            int a,b,c;
            void multiply (int n, int m) { a=n; b=m; c=a*b; };
            };

            沒有定義構(gòu)造函數(shù),


            編譯器自動假設(shè)它有以下constructor 成員函數(shù):

            • Empty constructor

              它是一個沒有任何參數(shù)的構(gòu)造函數(shù),被定義為nop (沒有語句)。它什么都不做。

              CExample::CExample () { };
            • Copy constructor

              它是一個只有一個參數(shù)的構(gòu)造函數(shù),該參數(shù)是這個class的一個對象,這個函數(shù)的功能是將被傳入的對象(object)的所有非靜態(tài)(non-static)成員變量的值都復(fù)制給自身這個object。

                 CExample::CExample (const CExample& rv) {
              a=rv.a; b=rv.b; c=rv.c;
              }

            必須注意:這兩個默認構(gòu)造函數(shù)(empty construction 和 copy constructor )

            只有在沒有其它構(gòu)造函數(shù)被明確定義的情況下才存在。

            如果任何其它有任意參數(shù)的構(gòu)造函數(shù)被定義了,這兩個構(gòu)造函數(shù)就都不存在了。

            在這種情況下,

            如果你想要有empty construction 和 copy constructor ,

            就必需要自己定義它們。

            posted @ 2008-12-04 18:04 henry08 閱讀(2107) | 評論 (5)編輯 收藏

            C在struct里面可以用public、private,默認的是public,而C++默認是private。

            C在struct里面可以用public、private,默認的是public,而C++默認是private。

            C在struct里面可以用public、private,默認的是public,而C++默認是private。

            posted @ 2008-12-04 18:01 henry08 閱讀(2774) | 評論 (1)編輯 收藏

            研究幾個C/C++編譯器

            今天在這里看一個程序,做了一點修改,拿Dev-C++編譯了一下,運行通過,只是有幾個Warning。文章作者說他是用LCC-Win32編譯的,上網(wǎng)查了一下,LCC-Win32現(xiàn)在已經(jīng)收費了,只在天空下載到一個LCC-Win32 V3.0。LCC-Win32是個C語言編譯器,編譯出來的程序只有14K,比起Dev-C++的460K來真是小太多了。一直很疑惑Dev-C++編譯出來的可執(zhí)行文件怎么那么大,難道GCC在Windows下只能編譯得那么大?還是我沒有配置好?

            在網(wǎng)上搜了一下其他Windows下的C++編譯器,看到這篇《微軟的免費 C++ 編譯器》,提到了微軟的Visual C++ Toolkit 2003。這套軟件是免費的,但是小氣的微軟已經(jīng)不再提供下載了。上網(wǎng)搜了一下,找到了微軟網(wǎng)站的VCToolkitSetup.exe文件下載鏈接,當然這個鏈接已經(jīng)不能用了,我直接扔到迅雷里下載,迅雷幫忙找到了兩個下載地址:地址一地址二。下載下來查看了一下MD5,90D8B963CA196AA9855B2CA6C3174C14,沒問題。

            文章中說這個VC 7.1可以用來編譯python和Firefox,不過我安裝的時候安裝程序自動重啟了我的系統(tǒng),555,今天不研究了,逃。

            Update:好像C++程序開頭加了#include <iostream>的話,生成的exe文件大小就會從20k左右上升到三、四百k。iostream不能不用啊,傷腦筋啊。另外,把編譯器選項里的連接器->剝除附加信息設(shè)成yes,可以有效的縮小編譯的程序的大小,大概可以從400多k縮小的200多k。
            http://yskin.net/2006/10/cpp-compiler.html

            posted @ 2008-12-03 13:50 henry08 閱讀(6938) | 評論 (16)編輯 收藏

            算法

            void main()
            {
                long a1 = 34, a2 = 23, a3 = 12;
                if( a1 > a2 )
                {
                    long temp = a1;
                    a1 = a2;
                    a2 = temp;
                }
                if( a1 > a3 )
                {
                    long temp = a1;
                    a1 = a3;
                    a3 = temp;
                }
                if( a2 > a3 )
                {
                    long temp = a2;
                    a2 = a3;
                    a3 = temp;
                }
            }
            上面就在每個if后面的復(fù)合語句中定義了一個臨時變量temp以借助編譯器的靜態(tài)分配內(nèi)存功能來提供臨時存放卡片的內(nèi)存。上面的元素交換并沒有按照前面所說映射成函數(shù),是因為在這里其只有三條語句且容易理解。如果要將交換操作定義為一函數(shù)
            如果要將交換操作定義為一函數(shù),則應(yīng)如下:
            void Swap( long *p1, long *p2 )             void Swap( long &r1, long &r2 )
            {                                           {
                long temp = *p1;                            long temp = r1;
                *p1 = *p2;                                  r1 = r2;
                *p2 = temp;                                 r2 = temp;
            }                                           }
            void main()                                 void main()
            {                                           {
                long a1 = 34, a2 = 23, a3 = 12;             long a1 = 34, a2 = 23, a3 = 12;
                if( a1 > a2 )                               if( a1 > a2 )
                    Swap( &a1, &a2 );                           Swap( a1, a2 );
                if( a1 > a3 )                               if( a1 > a3 )
                    Swap( &a1, &a3 );                           Swap( a1, a3 );
                if( a2 > a3 )                               if( a2 > a3 )
                    Swap( &a2, &a3 );                           Swap( a2, a3 );
            }                                           }
                先看左側(cè)的程序。上面定義了函數(shù)來表示給定盒子之間的交換操作,注意參數(shù)類型使用了long*,這里指針表示引用(應(yīng)注意指針不僅可以表示引用,還可有其它的語義,以后會提到)。



            下面看右側(cè)的程序。參數(shù)類型變成long&,和指針一樣,依舊表示引用,但注意它們的不同。后者表示它是一個別名,即它是一個映射,映射的地址是記錄作為參數(shù)的數(shù)字的地址,也就是說它要求調(diào)用此函數(shù)時,給出的作為參數(shù)的數(shù)字一定是有地址的數(shù)字

            posted @ 2008-11-27 16:31 henry08 閱讀(265) | 評論 (0)編輯 收藏

            函數(shù)

            上面的返回類型為void,前面提過,void是C++提供的一種特殊數(shù)字類型,其僅僅只是為了保障語法的嚴密性而已,即任何函數(shù)執(zhí)行后都要返回一個數(shù)字(后面將說明),而對于不用返回數(shù)字的函數(shù),則可以定義返回類型為void,這樣就可以保證語法的嚴密性。

            可以認為函數(shù)類型的地址類型的數(shù)字編譯器會隱式轉(zhuǎn)換成指針類型的數(shù)字


            重載函數(shù)表示函數(shù)名字一樣,但參數(shù)類型及個數(shù)不同的多個函數(shù)

             聲明是告訴編譯器一些信息,以協(xié)助編譯器進行語法分析,避免編譯器報錯。而定義是告訴編譯器生成一些代碼,并且這些代碼將由連接器使用。

            extern long a, *pA, &ra;
                上面就聲明(不是定義)了三個變量a、pA和ra。
            因為extern表示外部的意思,因此上面就被認為是告訴編譯器有三個外部的變量,為a、pA和ra,故被認為是聲明語句,所以上面將不分配任何內(nèi)存。
            同樣,對于函數(shù),它也是一樣的:
                extern void ABC( long );  或  extern long AB( short b );

            posted @ 2008-11-26 23:46 henry08 閱讀(191) | 評論 (0)編輯 收藏

            類型修飾符(type-specifier)

            數(shù)組和指針都是類型修飾符,之前提過的引用變量的“&”也是類型修飾符

            指針修飾符“*”——其總是接在變量名的前面,表示當前類型為原類型的指針。故:
            short a = 10, *pA = &a, **ppA = &pA;

             引用修飾符“&”——其總是接在變量名的前面,表示此變量不用分配內(nèi)存以和其綁定,而在說明類型時,則不能有它,下面說明。由于表示相應(yīng)變量不用分配內(nèi)存以生成映射,故其不像上述兩種類型修飾符,可以多次重復(fù)書寫,因為沒有意義

            posted @ 2008-11-26 15:52 henry08 閱讀(670) | 評論 (0)編輯 收藏

            僅列出標題
            共3頁: 1 2 3 
            国产午夜精品久久久久九九| 99久久国产综合精品麻豆| 国产真实乱对白精彩久久| 久久AAAA片一区二区| 久久人人爽人人爽人人片AV东京热 | 国产高潮久久免费观看| 久久精品夜色噜噜亚洲A∨| 久久强奷乱码老熟女网站| 久久久久亚洲精品中文字幕 | 欧洲国产伦久久久久久久| 久久午夜福利无码1000合集| 亚洲AV无一区二区三区久久| 97久久久精品综合88久久| 色婷婷久久综合中文久久一本| 久久精品人人做人人妻人人玩| 久久99精品国产麻豆不卡| 日日躁夜夜躁狠狠久久AV| 久久久久无码国产精品不卡| 国内精品久久久久影院日本 | 亚洲国产成人久久精品99| 国产精品久久久久久久| 久久精品人妻中文系列| 午夜视频久久久久一区 | 97久久天天综合色天天综合色hd| 日韩久久无码免费毛片软件| 国产一级做a爰片久久毛片| 久久亚洲国产成人影院| 久久精品综合一区二区三区| 免费国产99久久久香蕉| 久久国产精品-国产精品| 国产V综合V亚洲欧美久久| 伊人久久大香线蕉亚洲五月天| 久久综合九色综合久99| 污污内射久久一区二区欧美日韩 | 国产一级持黄大片99久久| 精品久久久久久无码专区| 欧美大香线蕉线伊人久久| 人妻无码中文久久久久专区| 中文字幕热久久久久久久| 国产偷久久久精品专区| 漂亮人妻被黑人久久精品|