一、尽可能使用单继承的方式进行系统设计(单继承+多个接口的方式)ios
二、尽可能保持系统中只存在单一继承树(建立一个顶层的抽象父类)c++
三、尽可能使用组合关系代替继承关系(后面会讲)数据结构
不幸的事实架构
(1)、c++语言的灵活性使得代码中能够存放多个继承树ide
(2)、c++编译器的差别使得一样的代码可能表现不一样的行为函数
如:new不成功的时候,之前的编译器都会是返回一个空指针,可是如今通常都会抛出一个异常,不一样的编译器抛出的异常可能不同,这就会使得移植性大大下降测试
建立DTLib::Object类的意义spa
(1)、遵循经典设计准则,全部的数据结构都继承自Object类设计
(2)、定义动态内存申请的行为,提升代码的移植性指针
一、头文件
#ifndef OBJECT_H #define OBJECT_H namespace DTLib { class Object { 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); virtual ~Object() = 0; }; } #endif // OBJECT_H
值得注意的是,重载new时函数声明后面都加上了 throw() ,表面new不成功不会抛出任何类型的异常。而将虚函数声明为纯虚函数的意义在于使其子类都用于虚函数表,能进行动态类型识别。
二、实现文件
#include "Object.h" #include <cstdlib> #include <iostream> using namespace std; namespace DTLib { void* Object::operator new (unsigned int size) throw() { cout << "Object::operator new:" << size << endl; return malloc(size); } void Object::operator delete(void* p) { cout << "Object::operator delete" << p << endl; free(p); } void* Object::operator new[] (unsigned int size) throw() { cout << "Object::operator new[]" << endl; return malloc(size); } void Object::operator delete[] (void* p) { cout << "Object::operator delete[]" << endl; free(p); } Object::~Object() { } }
要注意做为纯虚函数的析构函数也要进行定义(那些打印语句只是为了测试方便)
三、测试
#include <iostream> #include "Object.h" using namespace std; using namespace DTLib; class Test : public Object { public: int i; int j; }; class Child : public Test { public: int k; }; int main() { Object* obj1 = new Test(); Object* obj2 = new Child(); cout << "obj1=" << obj1 << endl; cout << "obj2=" << obj2 << endl; delete obj1; delete obj2; return 0; }
经过输出的结果能够看出,new一个对象时使用了咱们重载的版本,同时也含有了指向虚函数表的指针。
(1)、Object类是DTLib中数据结构类的顶层父类
(2)、Object类用于统一动态内存申请的行为
(3)、在堆中建立Object子类的对象,失败时返回NULL值
(4)、Object类为纯虚父类,全部子类都能进行动态类型识别