数据结构第12课 顶层父类的创建

本文学习自 狄泰软件学院 唐佐林老师的 数据结构课程


问题:我们创建数据结构为啥要创建一个顶层父类呢?意义和价值是什么?

在这里插入图片描述

创建可复用的数据结构库注意:
当代软件架构实践中的经验

  • 尽量使用单重继承的方式进行系统设计
    如果要用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

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux老A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值