構造方法用來初始化類的物件,與父類的其它成員不同,它不能被子類繼承(子類可以繼承父類所有的成員變數和成員方法,但不繼承父類的構造方法)。因此,在建立子類物件時,為了初始化從父類繼承來的資料成員,系統需要呼叫其父類的構造方法。
如果沒有顯式的建構函式,編譯器會給一個預設的建構函式,並且該預設的建構函式僅僅在沒有顯式地宣告建構函式情況下建立。
構造原則如下:
1. 如果子類沒有定義構造方法,則呼叫父類的無引數的構造方法。
2. 如果子類定義了構造方法,不論是無引數還是帶引數,在建立子類的物件的時候,首先執行父類無引數的構造方法,然後執行自己的構造方法。
3. 在建立子類物件時候,如果子類的建構函式沒有顯示呼叫父類的建構函式,則會呼叫父類的預設無參建構函式。
4. 在建立子類物件時候,如果子類的建構函式沒有顯示呼叫父類的建構函式且父類自己提供了無參建構函式,則會呼叫父類自己的無參建構函式。
5. 在建立子類物件時候,如果子類的建構函式沒有顯示呼叫父類的建構函式且父類只定義了自己的有參建構函式,則會出錯(如果父類只有有引數的構造方法,則子類必須顯示呼叫此帶參構造方法)。
6. 如果子類呼叫父類帶引數的構造方法,需要用初始化父類成員物件的方式,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream.h> class animal { public: animal(int height, int weight) { cout<<"animal construct"<<endl; } … }; class fish:public animal { public: fish():animal(400,300) { cout<<"fish construct"<<endl; } … }; void main() { fish fh; } |
在fish類的建構函式後,加一個冒號(:),然後加上父類的帶引數的建構函式。這樣,在子類的建構函式被呼叫時,系統就會去呼叫父類的帶引數的建構函式去構造物件。
例外像MFC常見的CDialog繼承可以看到這種例子..
標頭檔案中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#pragma once class CDrugDlg : public CDialogEx { DECLARE_DYNAMIC(CDrugDlg) public: CDrugDlg(CWnd* pParent = NULL); // 標準建構函式 virtual ~CDrugDlg(); // 對話方塊資料 enum { IDD = IDD_DRUG_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支援 DECLARE_MESSAGE_MAP() public: afx_msg void OnSize(UINT nType, int cx, int cy); virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg void OnDestroy(); }; |
實現檔案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// DrugDlg.cpp : 實現檔案 // #include "stdafx.h" #include "Medical.h" #include "DrugDlg.h" #include "afxdialogex.h" // CDrugDlg 對話方塊 IMPLEMENT_DYNAMIC(CDrugDlg, CDialog) CDrugDlg::CDrugDlg(CWnd* pParent /*=NULL*/) :CDialogEx(CDrugDlg::IDD, pParent) { } CDrugDlg::~CDrugDlg() { } |
這種初始化方式,還常用來對類中的常量(const)成員進行初始化,如下面的程式碼所示:
1 2 3 4 5 6 7 8 |
class point { public: point():x(0),y(0) private: const int x; const int y; }; |
當然,類中普通的成員變數也可以採取此種方式進行初始化,然而,這就沒有必要了..