1,数据结构库架构图:
2,创建可复用的数据结构类库,即在不同的工程和背景下面我们可以使用这个库,而当今工程的软件架构中的经验有:
1,尽量使用单重继承(多个接口)的方式进行系统设计;
2,尽量保持系统中只存在单一的继承树;
1,创建一个顶层的抽象父类来保证;
3,尽量使用组合关系代替继承关系;
1,如何使用链表实现栈和队列;
3,C++ 语言的缺点:
1,C++ 语言的灵活性是的代码中可以存在多个继承树;
1,工程表明多重继承只会带来更多的 bug;
2,工程表明多个继承树只会使得我们的代码质量下降;
2,C++ 编译器的差异使得同样的代码可能表现不同的行为;
1,C++ 只有规范,没有标准的 C++ 编译器;
2,比如 new 失败了会发生什么:
1,成功时候,编译器之间没有差异,失败的时候,早期的编译器返回空指针,但很多现代 C++ 编译器在 new 失败的时候会抛出一个标准库里面的异常;
2,给我们的这个库的设计带来了困难,要确保绝大多数编译器编译的时候会像我们期望的那样工作,new 操作失败了我们要怎么做?
4,创建 DTLib::Object 类的意义:
1,遵循经典设计准则,所有数据结构都继承自 Object 类;
1,可以规范动态内存申请时候的行为,不使用编译器默认提供的 new 的行为,自定义一个行为,保证不同的编译器中表现的行为是一致的;
2,尽量保证在这一个库里面,它是单一的继承树;
2,定义动态内存申请的行为,提高代码的移植性;
5,顶层父类的接口定义:
1,定义 new 和 delete 的重载函数是为了 new 和 delete 这个数据库当中的对象时,能有我们期望的行为,并且这个行为在不同的编译器下都是相同的;
2,析构函数定义为纯虚函数使得这一个顶层父类是一个抽象类,这样的析构函数定义也可以保证这一个类的所有子类中都有虚函数表的指针,这样可以使我们使用动态类型识别相关的技术;
6,顶层父类的创建:
1 #ifndef OBJECT_H 2 #define OBJECT_H 3 4 namespace DTLib 5 { 6 7 class Object 8 { 9 public: 10 /* 定义 new 和 delete 的重载函数是为了 new 和 delete 这个数据库当中的对象时,能有我们期望的行为,并且这个行为在不同的编译器下都是相同的; */ 11 void* operator new (unsigned int size) throw(); 12 void operator delete (void* p); 13 void* operator new[] (unsigned int size) throw(); 14 void operator delete[](void* p); 15 bool operator == (const Object& obj); 16 bool operator != (const Object& obj); 17 /* 析构函数定义为存续函数使得这一个顶层父类是一个抽象类,这样的析构函数定义也可以保证这一个类的所有子类中都有虚函数表的指针,这样可以使我们使用动态类型识别相关的技术; */ 18 virtual ~Object() = 0; 19 }; 20 21 } 22 23 #endif // OBJECT_H
7,顶层父类的实现:
1 #include "Object.h" 2 #include <cstdlib> 3 4 using namespace std; 5 6 namespace DTLib 7 { 8 void* Object::operator new (unsigned int size) throw() // 堆空间单个对象重载实现;throw()表示异常规格说明,表示当前函数不会抛出任何异常。 9 { 10 return malloc(size); // 未成功则直接返回空,所以在后续的对象中要判断空间是否为空 11 } 12 13 void Object::operator delete (void* p) 14 { 15 free(p); 16 } 17 18 void* Object::operator new[] (unsigned int size) throw() // 堆空间数组对象重载实现;如果申请不成功,直接返回空,没有异常;保证 new 失败的时候抛出一个空值,而不是抛出异常; 19 { 20 return malloc(size); // 未成功则直接返回空,所以在后续的对象中要判断空间是否为空; 21 } 22 23 void Object::operator delete[](void* p) 24 { 25 free(p); 26 } 27 28 bool Object::operator == (const Object& obj) // 为了后面 find 函数比较操作符的重载而定义 29 { 30 return (this == &obj ); // 类相等的依据是地址相等; 31 } 32 33 bool Object::operator != (const Object& obj)// 类不等的依据是地址不等; 34 { 35 return (this != &obj); 36 } 37 38 Object::~Object() 39 { 40 } 41 42 }
8,小结:
1,Object 类是 DTLib 中数据结构类的顶层父类;
2,Object 类用于统一动态内存申请的行为;
3,在堆中创建 Object 子类的对象,失败时返回 NULL 值;
4,Object 类为纯虚父类,所有子类都能进行动态类型识别;