程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++構造函數初始化順序

C++構造函數初始化順序

編輯:C++入門知識

C++構造函數初始化順序


1.構造函數、析構函數與拷貝構造函數介紹 構造函數 構造函數不能有返回值 缺省構造函數時,系統將自動調用該缺省構造函數初始化對象,缺省構造函數會將所有數據成員都初始化為零或空  創建一個對象時,系統自動調用構造函數 析構函數 析構函數沒有參數,也沒有返回值。不能重載,也就是說,一個類中只可能定義一個析構函數 如果一個類中沒有定義析構函數,系統也會自動生成一個默認的析構函數,為空函數,什麼都不做 調用條件:1.在函數體內定義的對象,當函數執行結束時,該對象所在類的析構函數會被自動調用;2.用new運算符動態構建的對象,在使用delete運算符釋放它時。 拷貝構造函數 拷貝構造函數實際上也是構造函數,具有一般構造函數的所有特性,其名字也與所屬類名相同。拷貝構造函數中只有一個參數,這個參數是對某個同類對象的引用。它在三種情況下被調用:   用類的一個已知的對象去初始化該類的另一個對象時; 函數的形參是類的對象,調用函數進行形參和實參的結合時; 函數的返回值是類的對象,函數執行完返回調用者。 【代碼】        /* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/9/25 */   #include "stdafx.h" #include <iostream> using namespace std;   class point { private:     int x, y; public:     point(int xx = 0, int yy = 0)     {         x = xx;         y = yy;         cout << "Constructor" << endl;     }     point(const point &p)     {         x = p.x;         y = p.y;         cout << "Copy Constructor" << endl;     }     ~point()     {         cout << "Destructor" << endl;     }     int get_x()     {         return x;     }     int get_y()     {         return y;     } };     void f(point p) {     // copy constructor     cout << p.get_x() << "  " << p.get_y() << endl;     // destructor }   point g() {     point a(7, 33); //constructor     return a; // copy constructor    temp object }   void test() {     point a(15, 22); // constructor     point b(a); //(1) copy constructor     cout << b.get_x() << "  " << b.get_y() << endl; // 15 22     f(b);//  (2) copy constructor     b = g(); // (3) copy constructor     cout << b.get_x() << "  " << b.get_y() << endl; // 7  33 }   int main() {     test();     return 0; } /* Constructor Copy Constructor 15      22 Copy Constructor 15      22 Destructor Constructor Copy Constructor Destructor Destructor 7       33 Destructor Destructor */ 2. 繼承關系中構造函數執行順序 (1)任何虛擬基類(virtual)的構造函數按照它們被繼承的順序構造; (2)任何非虛擬基類(non-virtual)的構造函數按照它們被繼承的順序構造; (3)任何成員對象(data member)的構造函數按照它們聲明的順序調用; (4)類自己的構造函數(self)。   【代碼】       /* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/9/27 */   #include "stdafx.h" #include <iostream> using namespace std;     class OBJ1 { public:     OBJ1()     {         cout << "OBJ1\n";     } };   class OBJ2 { public:     OBJ2()     {         cout << "OBJ2\n";     } };   class Base1 { public:     Base1()     {         cout << "Base1\n";     } };   class Base2 { public:     Base2()     {         cout << "Base2\n";     } };   class Base3 { public:     Base3()     {         cout << "Base3\n";     } };   class Base4 { public:     Base4()     {         cout << "Base4\n";     } };   class Derived : public Base1, virtual public Base2,     public Base3, virtual public Base4 { public:     Derived() : Base4(), Base3(), Base2(),         Base1(), obj2(), obj1()     {         cout << "Derived.\n";     } protected:     OBJ1 obj1;     OBJ2 obj2; };   void test() {     Derived aa;     cout << "This is ok.\n"; }   int main() {     test();     return 0; } /* Base2 Base4 Base1 Base3 OBJ1 OBJ2 Derived. This is ok. */ 【代碼2】     /* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/9/27 */   #include "stdafx.h" #include <iostream> using namespace std;   class Base1 { public:     Base1(int i)     {         cout << "Base1 " << i << endl;     } };   class Base2 { public:     Base2(int i)     {         cout << "Base2 " << i << endl;     } };   class Base3 { public:     Base3()     {         cout << "Base3 *" << endl;     } };   class Derived : public Base2,  public Base1, virtual public Base3 { public:     Derived(int a, int b, int c, int d, int e)         : Base1(a), b2(d), b1(c), Base2(b)     {         m = e;         cout << "Derived.\n";     } protected:     Base1 b1;     Base2 b2;     Base3 b3;     int m; };   void test() {     Derived aa(1, 2, 3, 4, 5);     cout << "This is ok.\n"; }   int main() {     test();     return 0; } /* Base3 * Base2 2 Base1 1 Base1 3 Base2 4 Base3 * Derived. This is ok. */ 分析:   (1) virtual    按照繼承順序:Base3   第一步:先繼承Base3,在初始化列表裡找不到Base3(), 則調用Base3裡的默認構造函數Base3(),打印"Base3  *"   (2)non-virtual   按照繼承順序:Base2,Base1   第二步:繼承Base2,在初始化列表中找Base2(b),調用Base2的構造函數Base2(2),打印"Base2 2"   第三步:繼承Base1,在初始化列表中找Base1(a),調用Base1的構造函數Base1(1),打印"Base1 1"    (3)data member   按照申明順序:b1,b2,b3   第四步:構造b1,在初始化列表中找b1(c),調用Base1的構造函數Base1(3),打印"Base1 3"   第五步:構造b2,在初始化列表中找b2(d),調用Base2的構造函數Base1(4),打印"Base2 4"   第六步:構造b3,在初始化列表中找不到b3(),調用Base3的構造函數Base3(),打印"Base3 *"   (4)self   第7步:執行自己的構造函數體,輸出"Derived."

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved