構造方法用來初始化類的對象,與父類的其它成員不同,它不能被子類繼承(子類可以繼承父類所有的成員變量和成員方法,但不繼承父類的構造方法)。因此,在創建子類對象時,為了初始化從父類繼承來的數據成員,系統需要調用其父類的構造方法。
如果沒有顯式的構造函數,編譯器會給一個默認的構造函數,並且該默認的構造函數僅僅在沒有顯式地聲明構造函數情況下創建。
構造原則如下:
1. 如果子類沒有定義構造方法,則調用父類的無參數的構造方法。
2. 如果子類定義了構造方法,不論是無參數還是帶參數,在創建子類的對象的時候,首先執行父類無參數的構造方法,然后執行自己的構造方法。
3. 在創建子類對象時候,如果子類的構造函數沒有顯示調用父類的構造函數,則會調用父類的默認無參構造函數。
4. 在創建子類對象時候,如果子類的構造函數沒有顯示調用父類的構造函數且父類自己提供了無參構造函數,則會調用父類自己的無參構造函數。
5. 在創建子類對象時候,如果子類的構造函數沒有顯示調用父類的構造函數且父類只定義了自己的有參構造函數,則會出錯(如果父類只有有參數的構造方法,則子類必須顯示調用此帶參構造方法)。
6. 如果子類調用父類帶參數的構造方法,需要用初始化父類成員對象的方式,比如:
- #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繼承可以看到這種例子..
頭文件中
- #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();
- };
// 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)成員進行初始化,如下面的代碼所示:
- class point
- {
- public:
- point():x(0),y(0)
- private:
- const int x;
- const int y;
- };
當然,類中普通的成員變量也可以采取此種方式進行初始化,然而,這就沒有必要了..