• 遵循经典设计准则
  • 改进的关键点
    Exception 类继承自 Object
       堆空间中创建异常对象失败后,返回NULL指针
       
    — 新增 InvalidOperationException 异常类
       成员函数调用时,如果状态不正确则抛出异常
       
    SmartPointer 类继承自 Object 类
       堆空间中创建智能指针对象失败后,返回NULL指针
  • DTLib的开发方式和注意事项
    — 迭代开发
       每次完成一个小的目标,持续开发,最终打造可复用类库
       
    — 单一继承树
       所有的类都继承于Object,规范堆对象创建的行为
       
    只抛异常,不处理异常
       使用 THROW_EXCEPTION 抛出异常,提高可移植性。
       因为可能项目里面不支持异常处理,我们选择把宏定义后面那部分给注释掉,使得我们的代码依旧照常运行,这时候觉得一开始把抛出异常设置成宏定义真是神来之笔。
       
    — 弱耦合性
       尽量不使用标准库中的类和函数,提高可移植性

SmartPointer.h

#ifndef SMARTPOINTER_H
#define SMARTPOINTER_H#include "Object.h"
namespace DTLib
{template <typename T>
class SmartPointer : public Object
{T* m_pointer;
public:SmartPointer(T* p = nullptr){m_pointer = p;}SmartPointer(const SmartPointer<T>& obj){m_pointer = obj.m_pointer;const_cast<SmartPointer<T>&>(obj).m_pointer = nullptr;}T* operator->(){return m_pointer;}T& operator*(){return *m_pointer;}SmartPointer<T>& operator=(const SmartPointer<T>& obj){if(this != &obj){delete m_pointer;m_pointer = obj.m_pointer;const_cast<SmartPointer<T>&>(obj).m_pointer = nullptr;}return *this;}bool isNull(){return (m_pointer == nullptr);}T* get(){return m_pointer;}~SmartPointer(){delete m_pointer;}
};
}
#endif // SMARTPOINTER_H

Exception.h

#ifndef EXCEPTION_H
#define EXCEPTION_H
#include "Object.h"namespace DTLib
{#define THROW_EXCEPTION(e, m) (throw e(m, __FILE__, __LINE__))class Exception : public Object
{protected:char* m_message;char* m_location;void init(const char* message, const char* file, int line);
public:Exception(const char* message);Exception(const char* file, int line);Exception(const char* message, const char* file, int line);Exception(const Exception& e);Exception& operator=(const Exception& e);virtual const char* message()const;virtual const char* location()const;virtual ~Exception() = 0;
};class ArithmeticException : public Exception
{public:ArithmeticException() : Exception(0){}ArithmeticException(const char* message) : Exception(message){}ArithmeticException(const char* file, int line) : Exception(file, line){}ArithmeticException(const char* message, const char* file, int line) : Exception(message, file, line){}ArithmeticException(const ArithmeticException& e) : Exception(e){}ArithmeticException& operator=(const ArithmeticException& e){Exception::operator=(e);return *this;}
};class NullPointerException : public Exception
{public:NullPointerException() : Exception(0){}NullPointerException(const char* message) : Exception(message){}NullPointerException(const char* file, int line) : Exception(file, line){}NullPointerException(const char* message, const char* file, int line) : Exception(message, file, line){}NullPointerException(const NullPointerException& e) : Exception(e){}NullPointerException& operator=(const NullPointerException& e){Exception::operator=(e);return *this;}
};class IndexOutOfBoundsException : public Exception
{public:IndexOutOfBoundsException() : Exception(0){}IndexOutOfBoundsException(const char* message) : Exception(message){}IndexOutOfBoundsException(const char* file, int line) : Exception(file, line){}IndexOutOfBoundsException(const char* message, const char* file, int line) : Exception(message, file, line){}IndexOutOfBoundsException(const IndexOutOfBoundsException& e) : Exception(e){}IndexOutOfBoundsException& operator=(const IndexOutOfBoundsException& e){Exception::operator=(e);return *this;}
};class NoEnoughMemoryException : public Exception
{public:NoEnoughMemoryException() : Exception(0){}NoEnoughMemoryException(const char* message) : Exception(message){}NoEnoughMemoryException(const char* file, int line) : Exception(file, line){}NoEnoughMemoryException(const char* message, const char* file, int line) : Exception(message, file, line){}NoEnoughMemoryException(const NoEnoughMemoryException& e) : Exception(e){}NoEnoughMemoryException& operator=(const NoEnoughMemoryException& e){Exception::operator=(e);return *this;}
};class InvalidParameterException : public Exception
{public:InvalidParameterException() : Exception(0){}InvalidParameterException(const char* message) : Exception(message){}InvalidParameterException(const char* file, int line) : Exception(file, line){}InvalidParameterException(const char* message, const char* file, int line) : Exception(message, file, line){}InvalidParameterException(const InvalidParameterException& e) : Exception(e){}InvalidParameterException& operator=(const InvalidParameterException& e){Exception::operator=(e);return *this;}
};class InvalidOperatorException : public Exception
{public:InvalidOperatorException() : Exception(0){}InvalidOperatorException(const char* message) : Exception(message){}InvalidOperatorException(const char* file, int line) : Exception(file, line){}InvalidOperatorException(const char* message, const char* file, int line) : Exception(message, file, line){}InvalidOperatorException(const InvalidOperatorException& e) : Exception(e){}InvalidOperatorException& operator=(const InvalidOperatorException& e){Exception::operator=(e);return *this;}
};
}#endif // EXCEPTION_H

Object.h

#ifndef OBJECT_H
#define OBJECT_Hnamespace 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

Exception.cpp

#include "Exception.h"
#include <cstring>
#include <cstdlib>namespace DTLib
{void Exception::init(const char* message, const char* file, int line)
{m_message = strdup(message);if(file != nullptr){char sl[16] = {0};m_location = reinterpret_cast<char*>(malloc(strlen(file) + strlen(sl) + 2));if(m_location != nullptr){itoa(line, sl, 10);m_location = strcpy(m_location, file);m_location = strcat(m_location, ":");m_location = strcat(m_location, sl);/*
13课的11min说明了原因      }
下面这个不要抛出异常。逻辑上看:父类里面抛出了一个子类的对象作为异常,就很奇怪。老爸还没诞生,先将儿子扔出去?代码上看:子类里面会调用父类的构造函数,就会形成死循环。
*///        else
//        {//            THROW_EXCEPTION(NoEnoughMemoryException, "Exception::init");
//        }}else{m_location = nullptr;}}
}Exception::Exception(const char* message)
{init(message, nullptr, 0);
}Exception::Exception(const char* file, int line)
{init(nullptr, file, line);
}Exception::Exception(const char* message, const char* file, int line)
{init(message, file, line);
}Exception::Exception(const Exception& e)
{m_message = strdup(e.m_message);m_location = strdup(e.m_location);
}Exception& Exception::operator=(const Exception& e)
{if(this != &e){free(m_message);free(m_location);m_message = strdup(e.m_message);m_location = strdup(e.m_location);}return *this;
}const char* Exception::message()const
{return m_message;
}const char* Exception::location()const
{return m_location;
}Exception::~Exception()
{free(m_message);free(m_location);
}}

Object.cpp

#include "Object.h"#include <iostream>
#include <cstdlib>
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()
{return malloc(size);
}void Object::operator delete[](void* p)
{free(p);
}Object::~Object()
{}}

main.cpp

#include <iostream>
#include "SmartPointer.h"
#include "Object.h"
#include "Exception.h"using namespace std;
using namespace DTLib;int main()
{SmartPointer<int>* pt = new SmartPointer<int>;delete pt;InvalidOperatorException* pi = new InvalidOperatorException;delete pi ;return 0;
}

C++数据结构第13课、类族结构的进化相关推荐

  1. 第十三课 类族结构的进化

    前几节我们开发的智能指针类和异常类族并没有继承自Object,现在我们需要将它们进行整合,作为DTLib这个类库的基础设施.整合的时候需要遵循现代软件的架构模式. 遵循经典设计准则 DTLib中所有类 ...

  2. Swift傻傻分不清楚系列(十一)类和结构体

    本页包含内容: 类和结构体对比 结构体和枚举是值类型 类是引用类型 类和结构体的选择 字符串(String).数组(Array).和字典(Dictionary)类型的赋值与复制行为 类和结构体是人们构 ...

  3. Swift 类与结构体

    前言 类和结构体是人们构建代码所用的一种通用且灵活的构造体.我们可以使用完全相同的语法规则来为类和结构体定义属性(常量.变量)和添加方法,从而扩展类和结构体的功能. 与其他编程语言所不同的是,Swif ...

  4. swift类和结构体

    2.9类和结构体 本页包含内容: 类和结构体对比 结构体和枚举是值类型 类是引用类型 类和结构体的选择 字符串.数组.和字典类型的赋值与复制行为 类和结构体是人们构建代码所用的一种通用且灵活的构造体. ...

  5. Swift 基本知识点之七类与结构体

    类和结构体对比 结构体和枚举是值类型 类是引用类型 类和结构体的选择 字符串(String).数组(Array).和字典(Dictionary)类型的赋值与复制行为 类和结构体是人们构建代码所用的一种 ...

  6. Swift学习:类和结构体

    类和结构体是人们构建代码所用的一种通用且灵活的构造体.我们可以使用完全相同的语法规则来为类和构造体定义属性(常量.变量)和添加方法,从而扩展类和构造体的功能. 与其他编程语言所不同的是,swift 并 ...

  7. Swift-2.9类和结构体

    本页包含内容: 类和结构体对比 结构体和枚举是值类型 类是引用类型 类和结构体的选择 字符串(String).数组(Array).和字典(Dictionary)类型的赋值与复制行为 类和结构体是人们构 ...

  8. swift 学习- 10 -- 类和结构体

    // '类和结构体' 是人们构建代码所使用的一种通用且灵活的构造体, 我们可以使用完全相同的语法规则来为 '类和结构体' 定义属性 (变量 和 常量) 和添加方法, 从而扩展 类和结构体 的功能 // ...

  9. 列表怎么有限的初始化为零_《零基础学习Android开发》第五课 类与面向对象编程1-1...

    视频:<零基础学习Android开发>第五课 类与面向对象编程1-1 类的定义.成员变量.构造方法.成员方法 一.从数据与逻辑相互关系审视代码 通过前面的课程,我们不断接触Java语言的知 ...

最新文章

  1. linux下热插拔事件的产生是怎样通知到用户空间,kobject_uevent_env之uevent【转】...
  2. Configuring the Java Virtual Manager (JVM)
  3. WHY MAKE ANOTHER APPLICATION AT ISSM?
  4. c语言中10转8和16的转换,(C语言)10进制转换2,8,16进制
  5. Java异常处理机制很有意思
  6. malloc和free
  7. gson读取json字符串_Java:JSON(Gson)从JSON字符串获取值
  8. Springboot2.0访问Redis集群
  9. 表格中序号怎计算机课程视频,【答疑】在Excel表格里输入了文字后怎么下拉顺序号啊?如何在表格里添加序号? - 视频教程线上学...
  10. 五步git操作搞定Github中fork的项目与原作者同步
  11. 以太坊平台评估 私有链和联盟链的机会与挑战
  12. python合成gif动图
  13. 浏览器访问网站标签页小图标显示
  14. Scratch-陶陶摘苹果
  15. cdr文字内容显示不出来_电脑装的字体cdr里面不显示怎么办
  16. 计算机教育杂志有核心期刊吗,计算机教育杂志是核心期刊吗?
  17. 论文阅读_(GIN)How Powerful are Graph Neural Networks
  18. Servlet-发送电子邮件
  19. 天龙手游角色删除服务器还有显示,天龙八部手游怎么删除角色_角色删除方法详解_玩游戏网...
  20. 以图搜图引擎 With Saprk

热门文章

  1. 单片机 电子电路 嵌入式 毕设 课设 私活 代做
  2. Boboniu Plays Chess
  3. Amazon亚马逊卖家设置World First(WF卡)收款教程!
  4. AWS亚马逊云注册图文详细教程,多币种充值优势分析
  5. python2代码转换python3(2018新)
  6. python将视频像素抓取替换导出mosaic效果的文本视频
  7. Vitalik:协议设计中的“封装复杂性” vs. “系统复杂性”
  8. Springboot 使用设计模式- 策略模式
  9. 美颜sdk算法总概——美白
  10. 【算法学习笔记六】递归之归纳法