如果没有为一个类显式地定义任何构造函数,编译器将自动为这个类生成默认构造函数。
由编译器创建的默认构造函数称为合成的默认构造函数,它将依据如下规则初始化类中的成员变量:
1.内置数据类型的初始化
内置数据类型是否自动初始化取决于变量定义的位置。如果变量在全局作用域内定义(即不在任何函数中)或定义为静态局部变量,则这些成员将被初始化为0。如果变量在局部作用域内定义,则这些成员没有初始化。
2.类类型变量的初始化
调用类的默认构造函数来初始化类类型变量。
小心地雷:基于以上的初始化规则,合成的默认构造函数一般适用于仅包含类类型成员的类。而对于含有内置数据类型或者复合类型成员的类,则通常应该定义他们自己的默认构造函数初始化这些成员。
举一个没有默认构造函数的例子:
- //==============================================================
- // ExamDefaultConstructor.h
- //
- // begin : 2012-05-13
- // author : zwq
- // describe: 默认构造函数例子。
- //==============================================================
- #if !defined(AFX_EXAMDEFAULTCONSTRUCTOR_H__2425242C_2C23_43E4_B38B_A039FCA3F929__INCLUDED_)
- #define AFX_EXAMDEFAULTCONSTRUCTOR_H__2425242C_2C23_43E4_B38B_A039FCA3F929__INCLUDED_
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
- // C++新标准头文件提倡的写法
- #include <string>
- // C++新标准中的标准库中的名称都是在std命名空间中
- using namespace std;
- //===============================================================
- //
- // CExamDefaultConstructor
- // 默认构造函数例子类
- //
- //===============================================================
- class CExamDefaultConstructor
- {
- public:
- // 没有提供默认的构造函数,编译器会为该类自动生成默认构造函数
- // 自动生成的默认构造函数称为合成的默认构造函数
- // CExamDefaultConstructor();
- virtual ~CExamDefaultConstructor();
- public:
- string m_strName; // 抽象标准库类型,有自己的默认构造函数,值为空串
- int m_nAge; // 基本内置数据类型,且在局部作用域内,系统不进行自动初始化,随机值
- static int m_nLevel;// 静态数据成员,且在局部作用域内,系统进行自动初始化,值为0
- };
- #endif // !defined(AFX_EXAMDEFAULTCONSTRUCTOR_H__2425242C_2C23_43E4_B38B_A039FCA3F929__INCLUDED_)
- //==============================================================
- // ExamDefaultConstructor.cpp
- //
- // begin : 2012-05-13
- // author : zwq
- // describe: 默认构造函数例子。
- //==============================================================
- #include "stdafx.h"
- #include "ExamDefaultConstructor.h"
- //===============================================================
- //
- // CExamDefaultConstructor
- // 默认构造函数例子类
- //
- //===============================================================
- // static数据成员必须在类定义体的外部定义(正好一次)。
- // 不像普通数据成员,static成员不是通过类构造函数进行初始化,而是应该在定义时进行初始化。
- // 在这里可以不显示初始化,系统将隐式初始化为0。
- int CExamDefaultConstructor::m_nLevel;
- // CExamDefaultConstructor::CExamDefaultConstructor()
- // {
- //
- // }
- CExamDefaultConstructor::~CExamDefaultConstructor()
- {
- }
执行上述程序:
- // CPlusPlusPrimer.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <iostream>
- #include "ExamDefaultConstructor.h"
- using namespace std;
- int main(int argc, char* argv[])
- {
- // 调用编译器合成的默认构造函数
- CExamDefaultConstructor exam;
- cout << "the name is " << exam.m_strName << endl;
- cout << "the age is " << exam.m_nAge << endl;
- cout << "the level is " << CExamDefaultConstructor::m_nLevel << endl;
- return 0;
- }
执行结果如下:
通过输出结果可以看出:
在合成的默认构造函数中,初始化变量m_strName时调用string的默认构造函数,初始化的结果为空串;初始化m_nAge时,由于该变量定义在了局部作用域内,则没有初始化,是运行时分配的随机值;静态数据成员m_nLevel被系统自动初始化为0。