至于为什么要创建一个顶层父类,在当代软件架构实践中的经验
- 尽量使用单重继承的方式进行系统设计
- 尽量保持系统中只存在单一的继承树
- 尽量使用组合关系代替继承关系
但是C++编译器的差异,使得同样的代码可能表现不同的行为,例如new操作失败后,不同的编译器,可能返回NULL空指针,也了能抛出一个固定的异常。这就导致代码的移植性变差,所以我们要创建一个 顶层父类MyLib::MyObject
- 遵循经典设计原则,所有数据结构都继承自MyObject类
- 统一定义动态内存申请的行为,提高代码的移植性,所有继承自MyObject顶层父类的子类,new与 delete都是使用自己定义的new、delete。
MyObject顶层父类如下
//MyObject.h头文件
#ifndef __MYOBJECT_H__
#define __MYOBJECT_H__
namespace MyLib
{
class MyObject
{
public:
void* operator new(unsigned int size) throw(); //该函数不会抛出异常
void operator delete(void * p);
void* operator new[] (unsigned int size) throw();
void operator delete[](void *p);
bool operator == (MyObject& obj);
bool operator != (MyObject& obj);
virtual ~MyObject() = 0; //将析构函数定义为纯虚函数,使得该类只能被继承
};
}
#endif //__MYOBJECT_H__
//MyObject.cpp源文件
#include "MyObject.h"
#include <cstdlib>
namespace MyLib
{
void* MyObject::operator new(unsigned int size) throw() //不抛异常,new失败后返回NULL
{
return malloc(size);
}
void MyObject::operator delete(void * p)
{
free(p);
}
void* MyObject::operator new[] (unsigned int size) throw()
{
return malloc(size);
}
void MyObject::operator delete[](void *p)
{
free(p);
}
bool MyObject::operator == (MyObject& obj)
{
return this == &obj;
}
bool MyObject::operator != (MyObject& obj)
{
return this != &obj;
}
MyObject::~MyObject()
{
}
}
到此为止,数据机构的顶层父类已经建立完毕,后续所有数据结构所有的类都将继承自该顶层父类,使得动态内存空间的申请与释放得到统一, 避免不同的编译器操作动态内存产生不同的结果。
总结
- MyObject 类时MyLib中数据结构类的顶层父类
- MyObject 类用于统一动态内存申请的行为
- 在堆中创建MyObject子类对象,失败时返回NULL值
- MyObject类为纯虚父类,所有子类都能进行动态类型识别