Метод конструктора используется для инициализации объектов класса. В отличие от других членов родительского класса, он не может быть унаследован подклассом (подкласс может наследовать все переменные-члены и методы-члены родительского класса, но не наследует методы конструктора родительского класса). Поэтому при создании объекта подкласса, чтобы инициализировать элементы данных, унаследованные от родительского класса, системе необходимо вызвать методы конструктора родительского класса.

Если явный конструктор отсутствует, компилятор предоставит конструктор по умолчанию, и этот конструктор по умолчанию создаётся только тогда, когда ни один конструктор явно не объявлен.

Принципы конструирования следующие:

  • 1. Если подкласс не определяет метод-конструктор, вызывается метод-конструктор родительского класса без аргументов.
  • 2. Если подкласс определяет метод-конструктор, без аргументов или с аргументами, при создании объекта подкласса сначала выполняется метод-конструктор родительского класса без аргументов, а затем выполняется его собственный метод-конструктор.
  • 3. При создании объекта подкласса, если конструктор подкласса явно не вызывает конструктор родительского класса, будет вызван конструктор родительского класса по умолчанию без аргументов.
  • 4. При создании объекта подкласса, если конструктор подкласса явно не вызывает конструктор родительского класса и сам родительский класс предоставляет конструктор без аргументов, будет вызван собственный конструктор родительского класса без аргументов.
  • 5. При создании объекта подкласса, если конструктор подкласса явно не вызывает конструктор родительского класса и родительский класс определяет только свой собственный конструктор с параметрами, возникнет ошибка (если у родительского класса есть только конструктор с параметрами, подкласс должен явно вызвать этот метод-конструктор с параметрами).
  • 6. Если подкласс вызывает конструктор родительского класса с параметрами, ему нужно сделать это путём инициализации объекта-члена родительского класса, например:

Пример

#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(); };

在 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; };

Конечно, обычные переменные-члены класса также можно инициализировать таким образом, но в этом нет необходимости..

Источник: http://blog.jobbole.com/109500/