本文学习自 狄泰软件学院 唐佐林老师的 数据结构课程
问题:我们创建数据结构为啥要创建一个顶层父类呢?意义和价值是什么?
创建可复用的数据结构库注意:
当代软件架构实践中的经验
-
尽量使用单重继承的方式进行系统设计
如果要用C++语言开发一个面向对象的系统,那么不要使用多继承,应该使用单重继承,实现多个不同的接口。不要让一个类继承多个父类。 -
尽量保持系统只存在单一的继承树
:通过创建一个顶层的抽象父类来保证 -
尽量使用组合关系代替继承关系
new操作如果失败会发生什么?
new成功的时候 各个编译器之间没有什么差异,但是new失败的情况,编译器之间就会产生不同的结果,比如早期的C++编译器在new失败的时候会返回一个空指针,但是很多现C++编译器在new失败的时候会抛出一个标准库里面的异常,这就给我们创建一个可复用的代码库带来了一定的困难。因为如果说new失败了,我们这个库里面的代码如何处理才能兼容绝大多数编译器。
- 遵循经典设计准则,所有数据结构都继承自Object类(顶层父类)
意义:规范动态内存申请时候的行为,我们不使用编译器默认提供的new,自己定义一个new,来保证在不同给编译器当中表现是一致的。
意义:尽量保证在我们是数据结构中是单一的继承树 - 定义动态内存申请行为,提高代码的移植性。
顶层父类接口定义
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);
//纯虚函数 将顶层父类编程 抽象类,也可以保证这个类的所有子类当中都有虚函数表的指针,使得我们使用动态类型识别相关技术了,即多态
~Object() = 0;
};
实验1
Object.h
#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.cpp
#include "Object.h"
#inlcude <cstdlib> //malloc
#include <iostream> //log
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:" << size <<endl;
free(p);
}
void* Object::operator new[] (unsigned int size) throw()
{
return malloc(size);
}
void Object::operaot delete[] (void* p)
{
free(p);
}
Object::~Object()
{
}
}
main.cpp
#inlcude <iostream>
#inlcude "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;
}
运行结果:
Object::operator new: 12
Object::operator new: 16
obj1 = 0x5719c8
obj2 = 0x5719c0
Object::operator delete: 0x5719c8
Object::operator delete: 0x5719c0
说明:
打印 “Object::operator new”" 说明没有调用系统的new,而是调用了顶层父类的new,
打印 “Object::operator new: 12” 说明 Test对象需要12个字节 12 = i(4)+j(4)+p(4:隐藏着的指向虚函数表的指针)
打印 “Object::operator new: 16” 说明 Child对象需要16个字节 16 = i(4)+j(4)+k(4)+p(4:隐藏着的指向虚函数表的指针)
打印 “Object::operator delete:” 说明删除时使用的不是系统delete 而是调用了顶层父类的delete