所谓默认构造函数的功能,就是在没有任何输入参数的情况下将对象进行初始化。一般在以下三种情况中,会认为类的默认构造函数是必要的:
1】产生一个对象数组的时候,数组的声明语法结构限制构造函数参数的提供,所以无法为数组中的对象提供构造参数,因此对象数组定义声明的时候,通常(虽然有三种方法可以一定程度上绕开这种限制:non-heap数组;指针数组;raw memory & placement new方法)必须要求类有默认构造方法;
2】实例化模板类的时候(或者类似的的类,虽然也可以通过设计来避免模板类对默认构造函数的需求);
3】虚基类中,如果虚基类中没有默认构造器,那么在设计子类的时候,就必须在每一层的继承中对基类按照构造函数原型的要求进行实例化(子类无法继承基类的构造函数)。
那么为什么不默认要求所有的类都必须有一个默认构造器呢?
1】这样会让对象在实例化的时候存在不确定性,因为很多时候对象的意义在于其所携带的字段信息,而非对象本身。单纯的初始化一个没有输入信息的对象是没有意义的,也让类的成员函数在处理对象的时候变得复杂,因为成员函数首先要判断对象是不是按照要求被正确、有意义的初始化了,以保证成员函数能正确的执行下去。
2】额外的默认构造函数会影响类的效率,因为上面这条原因中的测试需求会要求额外的测试空间以及测试时间。
代码实现例子如下
main.cpp文件
#include<iostream>
#include "EquipementPiece.h"
#include "ArrayTemplateClass.h"
#include "EquipmentPiece_3.h"
int main()
{
/** instance an object array with None Default ctor Class **/
//EquipementPiece eqPiece1; // error ,need default ctor
//EquipementPiece bestPieces[10]; // error,need default ctor
//EquipementPiece *bestPieces
// = new EquipementPiece[10]; // error,need default ctor
EquipementPiece eqPiece1(10); // work without De-ctor
EquipementPiece **bestPieces // work without De-ctor:must delete obj in the end for resource leaking
= new EquipementPiece*[10];
for (int iloop1 = 0; iloop1 < 10 ;iloop1 ++)
{
bestPieces[iloop1] = new EquipementPiece(iloop1);
}
for (int iloop1 = 0; iloop1 < 10 ;iloop1 ++)
{
delete bestPieces[iloop1];
}
// method a.1 ==> non-heap array:must delete obj in finally
int inA[3] = {9,5,1};
EquipementPiece bestPieces1[3] = {
EquipementPiece(inA[0]),
EquipementPiece(inA[1]),
EquipementPiece(inA[2])
};
// method a.2.1 ==> pointer array:must delete obj in the end for resource leaking
typedef EquipementPiece *PEP1;
PEP1 bestPieces2[3];
for (int iloop1 = 0; iloop1 < 3 ;iloop1 ++)
{
bestPieces2[iloop1] = new EquipementPiece(inA[3 - iloop1]);
}
for (int iloop1 = 0; iloop1 < 3 ;iloop1 ++)
{
delete bestPieces2[iloop1];
}
// method a.2.2 ==> pointer array:must delete obj in the end for resource leaking
typedef EquipementPiece *PEP2;
PEP2 *bestPieces3 =
new PEP2[3];
for (int iloop1 = 0; iloop1 < 3 ;iloop1 ++)
{
bestPieces3[iloop1] = new EquipementPiece(inA[iloop1]);
}
for (int iloop1 = 0; iloop1 < 3 ;iloop1 ++)
{
delete bestPieces3[iloop1];
}
// method a.3 ==> placement new
// special attention to the difference between "operator new" and "new operator"
void *rawMemory =
operator new[](5*sizeof(EquipementPiece));
EquipementPiece *bestPieces4 =
static_cast<EquipementPiece*>(rawMemory);
for (int iloop1 = 0 ;iloop1 < 5; iloop1 ++)
{
new(&bestPieces4) EquipementPiece(iloop1);
}
for (int iloop1 = 0 ;iloop1 < 5; iloop1 ++)
{
bestPieces4[iloop1].~EquipementPiece();
}
operator delete[](rawMemory);
/** instance an object array with template Class **/
//ArrayTemplateClass<int> arrayObj; // Error ,need De-ctor
/** instance an object with virtual Class **/
EquipmentPiece_3 eqPiece2;
return 0;
}
EquipmentPiece类声明文件
#ifndef EQUIPEMENTPIECE_H
#define EQUIPEMENTPIECE_H
class EquipementPiece
{
public:
EquipementPiece(int IDNumber);
protected:
private:
};
#endif
EquipmentPiece类源文件
#include "EquipementPiece.h"
EquipementPiece::EquipementPiece(int IDNumber)
{
}
模板类ArrayTemplateClass声明文件
#ifndef ARRAYTEMPLATECLASS_H
#define ARRAYTEMPLATECLASS_H
template<class T>
class ArrayTemplateClass
{
public:
ArrayTemplateClass(int size);
private:
T *data;
};
#endif
模板类ArrayTemplateClass源文件
#include "ArrayTemplateClass.h"
template<class T>
ArrayTemplateClass<T>::ArrayTemplateClass(int size)
{
data = new T(size);
}
EquipmentPiece_3的声明文件
#ifndef EQUIPMENTPIECE_3_H
#define EQUIPMENTPIECE_3_H
class EquipmentPiece_3
{
public:
EquipmentPiece_3(int IDNum = UNSPECIFIED);
private:
static const int UNSPECIFIED = 0;
};
#endif
EquipmentPiece_3源文件
#include "EquipmentPiece_3.h"
EquipmentPiece_3::EquipmentPiece_3(int IDNum )
{
}