• <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>

            Benjamin

            靜以修身,儉以養德,非澹薄無以明志,非寧靜無以致遠。
            隨筆 - 397, 文章 - 0, 評論 - 196, 引用 - 0
            數據加載中……

            C++基本概念之構造函數(constructor)(一)

            1.功能:創建(build objects)對象,將一連串的隨意的內存位變對象,也分配資源(memory, files, semaphores, sockets等),"ctor" 是構造函數(constructor)典型的縮寫。
            2.假定List是個類名,List x和 List x()的區別:前者聲明了一個List對象,后者則是一個函數,返回List類型。
            3.能否在一個構造函數中調用另一個構造函數?答案是否定的。
            假設類Fro有兩個構造函數Foo::Foo(char x)和Foo::Foo(char x,int y),那么下面的代碼
            class Foo {
             public:
               Foo(char x);
               Foo(char x, int y);
               ...
             };
             
             Foo::Foo(char x)
             {
               
            ...
               Foo(x, 0);  
            // this line does NOT help initialize the this object!!to initialize a temporary(臨時量), local object (not this), it immediately destructs  that temporary when control flows over,   
               
            ...
             }
            也可以組合這兩個構造函數,通過默認參數
            class Foo {
             public:
               Foo(char x, int y=0);  // this line combines the two constructors
               
            ...
             };
            如果沒有默認參數可用,那么我可以共享公用代碼在私有的Init函數中,如:
            class Foo {
             public:
               Foo(char x);
               Foo(char x, int y);
               ...
             private:
               void init(char x, int y);
             };
             
             Foo::Foo(char x)
             {
               init(x, int(x) + 7);
               
            ...
             }
             
             Foo::Foo(char x, int y)
             {
               init(x, y);
               
            ...
             }
             
             void Foo::init(char x, int y)
             {
               
            ...
             }

            不要嘗試把它用在布局new(placemement new)中,有些人認為可以new(this) Foo(x, int(x)+7)在Foo::Foo(char)中,這是絕對錯誤的。它會影響對象的構建位(constructed bits)。
            4.默認構造函數(default constructor )的參數可以使沒有,也可以使默認的參數。如:
            class Fred {
             public:
               Fred();   // Default constructor: can be called with no args
               
            ...
             }; 或
            class Fred {
             public:
               Fred(int i=3, int j=5);   // Default constructor: can be called with no args
               
            ...
             };
            5.建立對象數組時,哪個構造函數將被調用:
            如果沒有默認構造函數,那么創建對象數組將會出錯。如:
            class Fred {
             public:
               Fred(int i, int j);       assume there is no default constructor
               
            ...
             };
             
             int main()
             {
               Fred a[10];              
             ERROR: Fred doesn't have a default constructor
               Fred* p = new Fred[10];  
             ERROR: Fred doesn't have a default constructor
               
            ...
             }
            如果用std::vector<Fred> ,則可以不用默認構造函數。如:
            #include <vector>
             
             int main()
             {
               std::vector<Fred> a(10, Fred(5,7));   the 10 Fred objects in std::vector a will be initialized with Fred(5,7)
               
            ...
             }
            也可以現實初始化數組:也可以用placement new來手工初始化數組元素
            class Fred {
             public:
               Fred(int i, int j);       assume there is no default constructor
               
            ...
             };
             
             int main()
             {
               Fred a[10] = {
                 Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7),  
            // The 10 Fred objects are
                 Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7)   
            // initialized using Fred(5,7)
               };
               
            ...
             }

            一般的我們用vector來替代數組。
            6.構造函數中如何使用初始化列表(initialization lists)和賦值(assignment)
            在構造中使用初始化列表比賦值更有效率,后者比前者多了一個臨時變量,多了這個臨時變量的創建和銷毀的開銷。但是在內置數據類型(int,float等)時,二者差別不大。
            另一種情況是在構造中的成員對象會被以默認構造函數完整的構造,會分配一些缺省狀態下的內存或是文件,這樣如果在構造中如果使用表達式或復制失敗,是沒辦法來釋放資源或關閉文件的。
            在下面情況下不易使用初始化列表:類有兩個構造函數并且需要初始化這個數據成員按照不同的順序,或是有兩個數據成員自引用,或數據成員需要引用this對象,或者拋出一個異常之前要初始化這個this成員等。
            7.構造函數可以使用this指針嗎?可以,但是小心使用,甚至于在初始化列表中使用它。
            可以使用的情況:構造函數的函數體(或構造函數所調用的函數)能可靠地訪問基類中聲明的數據成員和/或構造函數所屬類里聲明的數據成員。這是因為所有這些數據成員被保證在構造函數函數體開始執行時已經被完整的建立。
            構造函數的函數體(或構造函數所調用的函數)不能向下調用被派生類重定義的虛函數。無論你如何調用虛成員函數:顯式使用this指針(如,this->method()),隱式的使用this指針(如,method()),或甚至在this對象上調用其他函數來調用該虛成員函數,原因:在基類的構造函數執行期間,派生類對象還未產生。
            下面的情況有時是可行的:如果傳遞 this 對象的任何一個數據成員給另一個數據成員的初始化程序,你必須確保該數據成員已經被初始化。他的優點是不依賴編譯器,但是你必須知道一些語言規則(例如,基類子對象首先被初始化(如果有多重和/或虛繼承,則查詢這個次序?。?,然后類中定義的數據成員根據在類中聲明的次序被初始化),如果不知道就不要使用這個this指針。
            8.命名的構造函數法(Named Constructor Idiom):
            作用就就是區分多個構造函數。
            結構:把構造放到private或protected處,提供一個返回對象的public static 方法。每種不同的構造對象的方法都有一個這樣的靜態方法。例子:
            class Point {
             public:
               Point(float x, float y);     // Rectangular coordinates
               Point(float r, float a);     
            // Polar coordinates (radius and angle)
               
            // ERROR: Overload is Ambiguous: Point::Point(float,float)
             };
             
             int main()
             {
               Point p = Point(5.7, 1.2);   
            // Ambiguous: Which coordinate system?
               
            ...
             }
            解決方法就是使用Named Constructor Idiom
            #include <cmath>               // To get sin() and cos()
             
             class Point {
             public:
               static Point rectangular(float x, float y);      
            // Rectangular coord's
               static Point polar(float radius, float angle);   
            // Polar coordinates
               
            // These static methods are the so-called "named constructors"
               
            ...
             private:
               Point(float x, float y);     
            // Rectangular coordinates
               float x_, y_;
             };
             
             inline Point::Point(float x, float y)
               : x_(x), y_(y) { }
             
             inline Point Point::rectangular(float x, float y)
             { return Point(x, y); }
             
             inline Point Point::polar(float radius, float angle)
             { return Point(radius*cos(angle), radius*sin(angle)); }


            int main()
             {
               Point p1 = Point::rectangular(5.7, 1.2);   // Obviously rectangular
               Point p2 = Point::polar(5.7, 1.2);         
            // Obviously polar
               
            ...
             }

            如果Point有派生類,構造就放在protected中。

            posted on 2009-12-05 01:41 Benjamin 閱讀(3126) 評論(0)  編輯 收藏 引用 所屬分類: C/C++

            久久人人爽人人爽人人片AV不| 久久99国产综合精品| 久久久这里有精品中文字幕| 久久久久无码中| 亚洲国产一成人久久精品| 69久久夜色精品国产69| 久久人妻少妇嫩草AV蜜桃| 亚洲乱码精品久久久久.. | 99久久er这里只有精品18| 久久99精品国产麻豆宅宅| 无码8090精品久久一区| 亚洲天堂久久精品| 久久精品国产亚洲av日韩| 亚洲国产成人久久综合区| 九九久久99综合一区二区| 亚洲午夜无码久久久久| 久久香蕉国产线看观看猫咪?v| 99久久婷婷免费国产综合精品| 性做久久久久久久久老女人| 久久99国产精一区二区三区| 久久频这里精品99香蕉久| 色综合久久88色综合天天| 久久综合久久自在自线精品自| 午夜精品久久影院蜜桃| 99久久精品国产毛片| 精品久久久久中文字幕日本| 一本一本久久a久久综合精品蜜桃| 精品视频久久久久| 国产福利电影一区二区三区,免费久久久久久久精 | 久久亚洲日韩看片无码| 伊人久久综合精品无码AV专区| 亚洲成人精品久久| 亚洲精品乱码久久久久久中文字幕 | 国产精品无码久久久久 | 国内精品伊人久久久久网站| 久久99久久99精品免视看动漫| 亚洲综合伊人久久综合| 99久久国产综合精品女同图片| 国内精品久久久久久久久电影网 | 久久久久久久97| 日本强好片久久久久久AAA|