• 数据结构实战开发教程(二)泛型编程简介、智能指针示例、异常类构建、顶层父类的创建


    八、泛型编程简介

    1、数据结构课程的特点

    • 专注于数据元素之间的关系
    • 专注于特定结构之上的算法
    • 数据结构课程并不关注数据元素的具体类型!

    2、问题

    如何为数据结构的学习选择合适的语言?

    3、经验分享

    支持泛型编程的语言最适合数据结构课程的学习?

    4、泛型编程的概念

    • 不考虑具体数据类型的编程方式

            

    5、C++中的函数模板

    • 一种特殊的函数可用不同类型进行调用
    • 看起来和普通函数很相似,区别是类型可被参数化

            

    6、函数模板的语法规则

    • template关键字用于声明开始进行泛型编程
    • typename关键字用于声明泛指类型

            

    7、函数模板的使用

    • 自动类型推导调用
    • 具体类型显示调用

            

    8、编程实验:函数模板初探

    与下一个实验在一起。

    9、C++中的类模板

    • 以相同的方式处理不同的类型
    • 在类声明前使用template进行标识
    • < typename T>用于说明类中使用的泛指类型 T

            

    10、类模板的应用

    • 只能显示指定具体类型,无法自动推导
    • 使用具体类型<Type>定义对象

            

    11、编程实验:类模板初探

    1. #include <iostream>
    2. using namespace std;
    3. template <typename T>
    4. void Swap(T& a, T& b)
    5. {
    6. T t = a;
    7. a = b;
    8. b = t;
    9. }
    10. template <typename T>
    11. class Op
    12. {
    13. public:
    14. T process(T v)
    15. {
    16. return v * v;
    17. }
    18. };
    19. int main()
    20. {
    21. int a = 2;
    22. int b = 1;
    23. Swap(a, b);
    24. cout << "a = " << a << " " << "b = " << b << endl;
    25. double c = 0.01;
    26. double d = 0.02;
    27. Swap<double>(d, c);
    28. cout << "c = " << c << " " << "d = " << d << endl;
    29. Op<int> opInt;
    30. Op<double> opDouble;
    31. cout << "5 * 5 = " << opInt.process(5) << endl;
    32. cout << "0.3 * 0.3 = " << opDouble.process(0.3) << endl;
    33. return 0;
    34. }

    12、小结

    • 模板是泛型编程理论在C++中的实现
    • 函数模板支持参数的自动推导显示指定
    • 类模板在使用时只能显示指定类型
    • 类模板非常适用于编写数据结构相关的代码

    九、智能指针示例

    1、内存泄漏(臭名昭著的Bug

    • 动态申请堆空间,用完后不归还
    • C++语言中没有垃圾回收的机制(c#、java、Python有)
    • 指针无法控制所指堆空间的生命周期

    2、当代C++软件平台中的智能指针

    • 指针生命周期结束时主动释放堆空间
    • 一片堆空间最多只能由一个指针标识
    • 杜绝指针运算和指针比较

    3、智能指针的设计方案

    • 通过类模板描述指针的行为
      • 能够定义不同类型的指针对象
    • 重载指针特征操作符->*
      • 利用对象模拟原生指针的行为

    4、编程实验:智能指针

    SmartPointer.h

    1. #ifndef SMARTPOINTER_H_
    2. #define SMARTPOINTER_H_
    3. /*******************************************************************************
    4. * Include Files *
    5. *******************************************************************************/
    6. #include "Pointer.h"
    7. /*******************************************************************************
    8. * Type Definition *
    9. *******************************************************************************/
    10. namespace DTLib
    11. {
    12. template <typename T> // 泛型编程 - 类模板
    13. class SmartPointer : public Pointer<T> // 基于普通指针类
    14. {
    15. public:
    16. SmartPointer(T* p = NULL) : Pointer<T>(p) // 构造函数 - 调用父类构造函数 - 默认指针为NULL
    17. {
    18. }
    19. SmartPointer(const SmartPointer<T>& obj) // 拷贝构造函数
    20. {
    21. this->m_pointer = obj.m_pointer; // 当前对象的堆空间 指向 引入的堆空间
    22. const_cast<SmartPointer<T>&>(obj).m_pointer = NULL; // 将原来的堆空间指针置NULL const_cast 去除对象的const属性
    23. }
    24. SmartPointer<T>& operator= (const SmartPointer<T>& obj) // 重载赋值操作符
    25. {
    26. if( this != &obj ) // 判断是否为 自赋值
    27. {
    28. T* p = this->m_pointer; //为了防止类异常抛出,所以最后释放堆空间
    29. this->m_pointer = obj.m_pointer; // 当前对象的堆空间 指向 引入的堆空间
    30. const_cast<SmartPointer<T>&>(obj).m_pointer = NULL; // 将原来的堆空间指针置NULL const_cast 去除对象的const属性
    31. delete p; // 释放当前指针指向的堆空间
    32. }
    33. return *this; // 返回自己(支持连续赋值)
    34. }
    35. ~SmartPointer() // 析构函数 - 释放智能指针对应的堆空间
    36. {
    37. delete this->m_pointer;
    38. }
    39. };
    40. }
    41. #endif // SMARTPOINTER_H_

    Pointer.h

    1. #ifndef POINTER_H_
    2. #define POINTER_H_
    3. /*******************************************************************************
    4. * Include Files *
    5. *******************************************************************************/
    6. #include "Object.h"
    7. /*******************************************************************************
    8. * Type Definition *
    9. *******************************************************************************/
    10. namespace DTLib
    11. {
    12. template < typename T > // 泛型编程 - 类模板 T
    13. class Pointer : public Object
    14. {
    15. protected: // protected 可以被子类直接访问; 不能被外界直接访问
    16. T* m_pointer;
    17. public:
    18. Pointer(T* p = NULL) // 构造函数 - 默认指针为NULL
    19. {
    20. m_pointer = p;
    21. }
    22. T* operator-> () // 重载 -> 返回指针地址
    23. {
    24. return m_pointer;
    25. }
    26. T& operator* () // 重载 * 返回值
    27. {
    28. return *m_pointer;
    29. }
    30. const T* operator-> () const // 重载 -> 返回指针地址 const对象只能调用const的成员函数
    31. {
    32. return m_pointer;
    33. }
    34. const T& operator* () const // 重载 * 返回值 const对象只能调用const的成员函数
    35. {
    36. return *m_pointer;
    37. }
    38. bool isNull() const // 判断当前的智能指针是否为空指针 const对象只能调用const的成员函数
    39. {
    40. return (m_pointer == NULL);
    41. }
    42. T* get() const // 获取智能指针的值 const对象只能调用const的成员函数
    43. {
    44. return m_pointer;
    45. }
    46. virtual ~Pointer() = 0; // 析构函数 纯虚函数(抽象类)
    47. };
    48. template < typename T >
    49. Pointer<T>::~Pointer()
    50. {
    51. }
    52. }
    53. #endif // POINTER_H_

    5、智能指针分析

    智能指针的使用军规:只能用来指向堆空间中的单个对象或者变量

    6、小结

    • 指针特征操作符( ->*)可以被重载
    • 重载指针特征符能够使用对象代替指针
    • 智能指针只能用于指向堆空间中的内存
    • 智能指针的意义在于最大程度的避免内存问题

    十、C++异常简介

    1、C++内置了异常处理的语法元素try ... catch

    • try语句处理正常代码逻辑
    • catch语句处理异常情况
    • try语句中的异常由对应的catch语句处理

            

    2C++通过throw语句抛出异常信息

            

    3、C++异常处理分析

    • throw抛出的异常必须被catch处理
      • 当前函数能够处理异常,程序继续往下执行
      • 当前函数无法处理异常,则函数停止执行,并返回
    • 未被处理的异常会顺着函数调用栈向上传播,直到被处理为止,否则程序将停止执行。

            

    4、编程实验:C++异常处理初探

    5、C++异常简介

    • 同一个try语句可以跟上多个catch语句
      • catch语句可以定义具体处理的异常类型
      • 不同类型的异常由不同的catch语句负责处理
      • try语句中可以抛出任何类型的异常
      • catch(.….)用于处理所有类型的异常
      • 任何异常都只能被捕获( catch )一次

    6、异常处理的匹配规则

            

    7、编程实验:异常类型匹配

    1. #include <iostream>
    2. using namespace std;
    3. double divide(double a, double b)
    4. {
    5. const double delta = 0.000000000000001;
    6. double ret = 0;
    7. if( !((-delta < b) && (b < delta)) ) {
    8. ret = a / b;
    9. }
    10. else {
    11. throw 0; // 产生除 0 异常
    12. }
    13. return ret;
    14. }
    15. void Demo1()
    16. {
    17. try
    18. {
    19. throw 'c';
    20. }
    21. catch(int i)
    22. {
    23. cout << "catch(int i)" << endl;
    24. }
    25. catch(double d)
    26. {
    27. cout << "catch(double d)" << endl;
    28. }
    29. catch(char c)
    30. {
    31. cout << "catch(char c)" << endl;
    32. }
    33. }
    34. void Demo2()
    35. {
    36. throw 0.0001; // "D.T.Software"; // const char*
    37. }
    38. int main()
    39. {
    40. cout << "main() begin" << endl;
    41. try
    42. {
    43. double c = divide(1, 1);
    44. cout << "c = " << c << endl;
    45. }
    46. catch(...)
    47. {
    48. cout << "Divided by zero..." << endl;
    49. }
    50. Demo1();
    51. try
    52. {
    53. Demo2();
    54. }
    55. catch(char* c)
    56. {
    57. cout << "catch(char* c)" << endl;
    58. }
    59. catch(const char* cc)
    60. {
    61. cout << "catch(char* cc)" << endl;
    62. }
    63. catch(...)
    64. {
    65. cout << "catch(...)" << endl;
    66. }
    67. cout << "main() end" << endl;
    68. return 0;
    69. }

    8、小结

    • C++中直接支持异常处理的概念
    • try... catch...是C++中异常处理的专用语句
    • try语句处理正常代码逻辑,catch语句处理异常情况
    • 同一个try语句可以跟上多个catch语句
    • 异常处理必须严格匹配,不进行任何的类型转换

     

    十一、异常类构建

    1、异常类构建

    • 异常的类型可以是自定义类类型
    • 对于类类型异常的匹配依旧是至上而下严格匹配
    • 赋值兼容性原则在异常匹配中依然适用
    • 一般而言
      • 匹配子类异常的catch放在上部
      • 匹配父类异常的catch放在下部

    2、现代C++库必然包含充要的异常类族

    • 异常类是数据结构类所依赖的基础设施

            

    3、异常类功能定义

            

    4、异常类中的接口定义

    5、编程实验:创建异常类族

    Exception.cpp

    1. /*******************************************************************************
    2. * Include _Files *
    3. *******************************************************************************/
    4. #include "Exception.h"
    5. #include <cstring>
    6. #include <cstdlib>
    7. #include <cstdio>
    8. using namespace std;
    9. /*******************************************************************************
    10. * Type Definition *
    11. *******************************************************************************/
    12. namespace DTLib
    13. {
    14. /**********************************************************************
    15. * Function: Exception::init()
    16. * Description: 辅助初始化函数
    17. * Table Accessed:
    18. * Table Updated:
    19. * Input: _message 异常的说明信息
    20. * _file 发生异常的文件名
    21. * _line 发生异常的行号
    22. * Output: m_message 异常的说明信息 (类中成员)
    23. * m_location 异常的文件名和行号 (类中成员)
    24. * Return:
    25. * Others: 用于被重载函数调用
    26. * Modify Date Version Author Modification
    27. * ------------------------------------------------------------
    28. * 2022/03/09 1.0 Create
    29. **********************************************************************/
    30. void Exception::init(const char* _message, const char* _file, int _line)
    31. {
    32. #define STR_CAT_LINE 16 // 行号字符串拼接长度
    33. #define STR_CAT_SYMBOL 2 // 文件名和行号的隔离符号(:); 字符串结束符\0
    34. // 获取 异常的说明信息
    35. m_message = (_message ? strdup(_message) : NULL); //判断_message是否为空(strdup默认入参不为空) strdup将字符串复制到堆空间,返回指针地址
    36. // 获取 发生异常的文件名和行号
    37. if( _file != NULL )
    38. {
    39. // 将行号转为字符串类型
    40. char acLineStrcat[STR_CAT_LINE] = {0};
    41. // itoa(_line, acLineStrcat, 10);
    42. snprintf(acLineStrcat, sizeof(acLineStrcat), "%d", _line);
    43. // 申请堆空间,进行拼接文件名和行号
    44. m_location = static_cast<char*>(malloc(strlen(_file) + strlen(acLineStrcat) + STR_CAT_SYMBOL));
    45. if( m_location != NULL )
    46. {
    47. m_location = strcpy(m_location, _file); // 拷贝文件名
    48. m_location = strcat(m_location, ":"); // 拼接 :
    49. m_location = strcat(m_location, acLineStrcat); // 拼接 行号
    50. }
    51. }
    52. else
    53. {
    54. m_location = NULL;
    55. }
    56. }
    57. /**********************************************************************
    58. * Function: Exception::Exception()
    59. * Description: 重载函数
    60. * Input: _message 异常的说明信息
    61. * _file 发生异常的文件名
    62. * _line 发生异常的行号
    63. * Others: 用于被重载函数调用
    64. * Modify Date Version Author Modification
    65. * ------------------------------------------------------------
    66. * 2022/03/09 1.0 Create
    67. **********************************************************************/
    68. Exception::Exception(const char* _message)
    69. {
    70. init(_message, NULL, 0);
    71. }
    72. Exception::Exception(const char* _file, int _line)
    73. {
    74. init(NULL, _file, _line);
    75. }
    76. Exception::Exception(const char* _message, const char* _file, int _line)
    77. {
    78. init(_message, _file, _line);
    79. }
    80. /**********************************************************************
    81. * Function: Exception::Exception()
    82. * Description: 拷贝函数重载(深拷贝)
    83. * Input: Exception 传入待拷贝的Exception类
    84. * Output: Exception 创建的Exception类 (类中成员)
    85. * Return:
    86. * Others: 深拷贝 - 成员指向了动态内存空间
    87. * Modify Date Version Author Modification
    88. * ------------------------------------------------------------
    89. * 2022/03/09 1.0 Create
    90. **********************************************************************/
    91. Exception::Exception(const Exception& _eWaitCopy)
    92. {
    93. m_message = strdup(_eWaitCopy.m_message);
    94. m_location = strdup(_eWaitCopy.m_location);
    95. }
    96. /**********************************************************************
    97. * Function: Exception::Exception()
    98. * Description: 赋值运算符重载
    99. * Input: Exception 传入待拷贝的Exception类
    100. * Output: Exception 创建的Exception类 (类中成员)
    101. * Return: Exception 当前类的指针
    102. * Others: 返回当前类的指针,代表允许连续赋值
    103. * Modify Date Version Author Modification
    104. * ------------------------------------------------------------
    105. * 2022/03/09 1.0 Create
    106. **********************************************************************/
    107. Exception& Exception::operator= (const Exception& _eWaitCopy)
    108. {
    109. if( this != &_eWaitCopy )
    110. {
    111. free(m_message);
    112. free(m_location);
    113. m_message = strdup(_eWaitCopy.m_message);
    114. m_location = strdup(_eWaitCopy.m_location);
    115. }
    116. return *this;
    117. }
    118. /**********************************************************************
    119. * Function: Exception::message()
    120. * Description: 返回异常的说明信息的指针
    121. * Input:
    122. * Output:
    123. * Return: char* m_message 返回异常的说明信息的指针
    124. * Others:
    125. * Modify Date Version Author Modification
    126. * ------------------------------------------------------------
    127. * 2022/03/09 1.0 Create
    128. **********************************************************************/
    129. const char* Exception::message() const
    130. {
    131. return m_message;
    132. }
    133. /**********************************************************************
    134. * Function: Exception::location()
    135. * Description: 返回异常文件名和行号的指针
    136. * Input:
    137. * Output:
    138. * Return: char* m_location 返回异常文件名和行号的指针
    139. * Others:
    140. * Modify Date Version Author Modification
    141. * ------------------------------------------------------------
    142. * 2022/03/09 1.0 Create
    143. **********************************************************************/
    144. const char* Exception::location() const
    145. {
    146. return m_location;
    147. }
    148. /**********************************************************************
    149. * Function: Exception::~Exception()
    150. * Description: 析构函数
    151. * Input:
    152. * Output:
    153. * Return:
    154. * Others: 纯虚函数(抽象类) - 纯虚函数的实现由子类完成,这里是个例外,但凡定义析构函数就必须要提供实现,不管是不是纯虚的.
    155. * Modify Date Version Author Modification
    156. * ------------------------------------------------------------
    157. * 2022/03/09 1.0 Create
    158. **********************************************************************/
    159. Exception::~Exception()
    160. {
    161. free(m_message);
    162. free(m_location);
    163. }
    164. }

    Exception.h

    1. #ifndef EXCEPTION_H_
    2. #define EXCEPTION_H_
    3. /*******************************************************************************
    4. * Include Files *
    5. *******************************************************************************/
    6. #include "Object.h"
    7. /*******************************************************************************
    8. * Type Definition *
    9. *******************************************************************************/
    10. namespace DTLib
    11. {
    12. #define THROW_EXCEPTION(e, m) (throw e(m, __FILE__, __LINE__)) // 异常类型;说明信息
    13. /****** 异常父类 ******/
    14. class Exception : public Object
    15. {
    16. protected:
    17. char* m_message; // 当前异常的说明信息
    18. char* m_location; // 当前异常的位置信息
    19. void init(const char* _message, const char* _file, int _line); // 辅助初始化 - 定义了多个重载函数
    20. public:
    21. Exception(const char* message); // 构造函数 - 重载函数
    22. Exception(const char* file, int line); // 构造函数 - 重载函数
    23. Exception(const char* message, const char* file, int line); // 构造函数 - 重载函数
    24. Exception(const Exception& _eWaitCopy); // 拷贝构造函数
    25. Exception& operator= (const Exception& _eWaitCopy); // 赋值构造函数
    26. virtual const char* message() const; // 异常对象的说明信息
    27. virtual const char* location() const; // 异常对象的位置信息
    28. virtual ~Exception() = 0; // 纯虚函数(抽象类) - 析构函数
    29. };
    30. /****** 计算异常子类 ******/
    31. class ArithmeticException : public Exception
    32. {
    33. public:
    34. // 显式调用父类构造函数
    35. ArithmeticException() : Exception(0) { }
    36. ArithmeticException(const char* message) : Exception(message) { }
    37. ArithmeticException(const char* file, int line) : Exception(file, line) { }
    38. ArithmeticException(const char* message, const char* file, int line) : Exception(message, file, line) { }
    39. // 显式调用父类拷贝构造函数
    40. ArithmeticException(const ArithmeticException& eWaitCopy) : Exception(eWaitCopy) { }
    41. // 调用父类赋值重载函数
    42. ArithmeticException& operator= (const ArithmeticException& eWaitCopy)
    43. {
    44. Exception::operator=(eWaitCopy);
    45. return *this;
    46. }
    47. };
    48. /****** 空指针异常子类 ******/
    49. class NullPointerException : public Exception
    50. {
    51. public:
    52. // 显式调用父类构造函数
    53. NullPointerException() : Exception(0) { }
    54. NullPointerException(const char* message) : Exception(message) { }
    55. NullPointerException(const char* file, int line) : Exception(file, line) { }
    56. NullPointerException(const char* message, const char* file, int line) : Exception(message, file, line) { }
    57. // 显式调用父类拷贝构造函数
    58. NullPointerException(const NullPointerException& eWaitCopy) : Exception(eWaitCopy) { }
    59. // 调用父类赋值重载函数
    60. NullPointerException& operator= (const NullPointerException& eWaitCopy)
    61. {
    62. Exception::operator=(eWaitCopy);
    63. return *this;
    64. }
    65. };
    66. /****** 越界异常子类 ******/
    67. class IndexOutOfBoundsException : public Exception
    68. {
    69. public:
    70. // 显式调用父类构造函数
    71. IndexOutOfBoundsException() : Exception(0) { }
    72. IndexOutOfBoundsException(const char* message) : Exception(message) { }
    73. IndexOutOfBoundsException(const char* file, int line) : Exception(file, line) { }
    74. IndexOutOfBoundsException(const char* message, const char* file, int line) : Exception(message, file, line) { }
    75. // 显式调用父类拷贝构造函数
    76. IndexOutOfBoundsException(const IndexOutOfBoundsException& eWaitCopy) : Exception(eWaitCopy) { }
    77. // 调用父类赋值重载函数
    78. IndexOutOfBoundsException& operator= (const IndexOutOfBoundsException& eWaitCopy)
    79. {
    80. Exception::operator=(eWaitCopy);
    81. return *this;
    82. }
    83. };
    84. /****** 内存不足异常子类 ******/
    85. class NoEnoughMemoryException : public Exception
    86. {
    87. public:
    88. // 显式调用父类构造函数
    89. NoEnoughMemoryException() : Exception(0) { }
    90. NoEnoughMemoryException(const char* message) : Exception(message) { }
    91. NoEnoughMemoryException(const char* file, int line) : Exception(file, line) { }
    92. NoEnoughMemoryException(const char* message, const char* file, int line) : Exception(message, file, line) { }
    93. // 显式调用父类拷贝构造函数
    94. NoEnoughMemoryException(const NoEnoughMemoryException& eWaitCopy) : Exception(eWaitCopy) { }
    95. // 调用父类赋值重载函数
    96. NoEnoughMemoryException& operator= (const NoEnoughMemoryException& eWaitCopy)
    97. {
    98. Exception::operator=(eWaitCopy);
    99. return *this;
    100. }
    101. };
    102. /****** 参数错误异常子类 ******/
    103. class InvalidParameterException : public Exception
    104. {
    105. public:
    106. // 显式调用父类构造函数
    107. InvalidParameterException() : Exception(0) { }
    108. InvalidParameterException(const char* message) : Exception(message) { }
    109. InvalidParameterException(const char* file, int line) : Exception(file, line) { }
    110. InvalidParameterException(const char* message, const char* file, int line) : Exception(message, file, line) { }
    111. // 显式调用父类拷贝构造函数
    112. InvalidParameterException(const InvalidParameterException& eWaitCopy) : Exception(eWaitCopy) { }
    113. // 调用父类赋值重载函数
    114. InvalidParameterException& operator= (const InvalidParameterException& eWaitCopy)
    115. {
    116. Exception::operator=(eWaitCopy);
    117. return *this;
    118. }
    119. };
    120. /****** 成员函数调用异常子类 ******/
    121. class InvalidOperationException : public Exception
    122. {
    123. public:
    124. // 显式调用父类构造函数
    125. InvalidOperationException() : Exception(0) { }
    126. InvalidOperationException(const char* message) : Exception(message) { }
    127. InvalidOperationException(const char* file, int line) : Exception(file, line) { }
    128. InvalidOperationException(const char* message, const char* file, int line) : Exception(message, file, line) { }
    129. // 显式调用父类拷贝构造函数
    130. InvalidOperationException(const InvalidOperationException& eWaitCopy) : Exception(eWaitCopy) { }
    131. // 调用父类赋值重载函数
    132. InvalidOperationException& operator= (const InvalidOperationException& eWaitCopy)
    133. {
    134. Exception::operator=(eWaitCopy);
    135. return *this;
    136. }
    137. };
    138. }
    139. #endif // EXCEPTION_H_

    6、设计原则

    在可复用代码库设计时,尽量使用面向对象技术进行架构,尽量使用异常处理机制分离正常逻辑和异常逻辑。

    7、小结

    • 现代C++库必然包含充要的异常类族
    • 所有库中的数据结构类都依赖于异常机制
    • 异常机制能够分离库中代码的正常逻辑异常逻辑

            

    十二、顶层父类的创建

    1、当代软件架构实践中的经验

    • 尽量使用单重继承的方式进行系统设计
    • 尽量保持系统中只存在单一的继承树
    • 尽量使用组合关系代替继承关系

    2、不幸的事实

    • C++语言的灵活性使得代码中可以存在多个继承树
    • C++编译器的差异使得同样的代码可能表现不同的行为

    new操作如果失败会发生什么?

    3、创建DTLib::object类的意义

    • 遵循经典设计准则,所有数据结构都继承自Object
    • 定义动态内存申请的行为,提高代码的移植性,避免不同编译器的影响

    4、顶层父类的接口定义

            

    5、编程实验:顶层父类的创建

    Object.h

    1. #ifndef OBJECT_H_
    2. #define OBJECT_H_
    3. /*******************************************************************************
    4. * Include _Files *
    5. *******************************************************************************/
    6. #include <cstdlib>
    7. /*******************************************************************************
    8. * Type Definition *
    9. *******************************************************************************/
    10. namespace DTLib
    11. {
    12. class Object
    13. {
    14. public:
    15. void* operator new (size_t size) throw(); // 重载 new
    16. void operator delete (void* p); // 重载 delete
    17. void* operator new[] (size_t size) throw(); // 重载 new[]
    18. void operator delete[] (void* p); // 重载 delete[]
    19. bool operator == (const Object& obj); // 重载 == 自定义类可能会出现比较操作符,此处为默认写法 - 判断地址是否相同
    20. bool operator != (const Object& obj); // 重载 != 自定义类可能会出现比较操作符,此处为默认写法 - 判断地址是否相同
    21. virtual ~Object() = 0; // 析构函数(纯虚函数 抽象类)
    22. };
    23. }
    24. #endif // OBJECT_H_

    Object.cpp

    1. /*******************************************************************************
    2. * Include _Files *
    3. *******************************************************************************/
    4. #include "Object.h"
    5. #include <cstdlib>
    6. /*******************************************************************************
    7. * Type Definition *
    8. *******************************************************************************/
    9. using namespace std;
    10. namespace DTLib
    11. {
    12. /**********************************************************************
    13. * Function: Object::operator new()
    14. * Description: 重载 new
    15. * Table Accessed:
    16. * Table Updated:
    17. * Input: size 字节大小
    18. * Output: void* 指针地址
    19. * Return:
    20. * Others: throw() 这个重载函数不会抛出任何异常
    21. * Modify Date Version Author Modification
    22. * ------------------------------------------------------------
    23. * 2022/03/09 1.0 Create
    24. **********************************************************************/
    25. void* Object::operator new (size_t size) throw()
    26. {
    27. return malloc(size);
    28. }
    29. /**********************************************************************
    30. * Function: Object::operator delete()
    31. * Description: 重载 delete
    32. * Table Accessed:
    33. * Table Updated:
    34. * Input: void* 指针地址
    35. * Output:
    36. * Return:
    37. * Others:
    38. * Modify Date Version Author Modification
    39. * ------------------------------------------------------------
    40. * 2022/03/09 1.0 Create
    41. **********************************************************************/
    42. void Object::operator delete (void* p)
    43. {
    44. free(p);
    45. }
    46. /**********************************************************************
    47. * Function: Object::operator new[]()
    48. * Description: 重载 new[](数组)
    49. * Table Accessed:
    50. * Table Updated:
    51. * Input: size 字节大小
    52. * Output: void* 指针地址
    53. * Return:
    54. * Others: throw() 这个重载函数不会抛出任何异常
    55. * Modify Date Version Author Modification
    56. * ------------------------------------------------------------
    57. * 2022/03/09 1.0 Create
    58. **********************************************************************/
    59. void* Object::operator new[] (size_t size) throw()
    60. {
    61. return malloc(size);
    62. }
    63. /**********************************************************************
    64. * Function: Object::operator delete[]()
    65. * Description: 重载 delete[](数组)
    66. * Table Accessed:
    67. * Table Updated:
    68. * Input: void* 指针地址
    69. * Output:
    70. * Return:
    71. * Others:
    72. * Modify Date Version Author Modification
    73. * ------------------------------------------------------------
    74. * 2022/03/09 1.0 Create
    75. **********************************************************************/
    76. void Object::operator delete[] (void* p)
    77. {
    78. free(p);
    79. }
    80. /**********************************************************************
    81. * Function: Object::operator ==()
    82. * Description: ==重载函数
    83. * Table Accessed:
    84. * Table Updated:
    85. * Input:
    86. * Output:
    87. * Return:
    88. * Others:
    89. * Modify Date Version Author Modification
    90. * ------------------------------------------------------------
    91. * 2022/03/09 1.0 Create
    92. **********************************************************************/
    93. bool Object::operator == (const Object& obj)
    94. {
    95. return (this == &obj);
    96. }
    97. /**********************************************************************
    98. * Function: Object::operator !=()
    99. * Description: !=重载函数
    100. * Table Accessed:
    101. * Table Updated:
    102. * Input:
    103. * Output:
    104. * Return:
    105. * Others:
    106. * Modify Date Version Author Modification
    107. * ------------------------------------------------------------
    108. * 2022/03/09 1.0 Create
    109. **********************************************************************/
    110. bool Object::operator != (const Object& obj)
    111. {
    112. return (this != &obj);
    113. }
    114. /**********************************************************************
    115. * Function: Object::~Object()
    116. * Description: 析构函数
    117. * Table Accessed:
    118. * Table Updated:
    119. * Input:
    120. * Output:
    121. * Return:
    122. * Others:
    123. * Modify Date Version Author Modification
    124. * ------------------------------------------------------------
    125. * 2022/03/09 1.0 Create
    126. **********************************************************************/
    127. Object::~Object()
    128. {
    129. }
    130. }

    6、小结

    • Object类是DTLib中数据结构类的顶层父类
    • Object类用于统一动态内存申请的行为
    • 在堆中创建Object子类的对象,失败时返回NULL
    • Object类为纯虚父类,所有子类都能进行动态类型识别

     

    十三、类族结构的进化

    1、遵循经典设计准则

    • DTLib 中的所有类位于单一的继承树

            

    2、改进的关键点

    • Exception类继承自Object
      • 堆空间中创建异常对象失败时,返回NULL指针
    • 新增InvalidOperationException异常类
      • 成员函数调用时,如果状态不正确则抛出异常
    • SmartPointer 类继承自Object
      • 堆空间中创建智能指针对象失败时,返回NULL指针

    3、编程实验:类族结构的进化

    Exception.cpp

    Exception.h

    与上一个相同

    4DTLib 开发方式注意事项

    • 迭代开发
      • 每次完成一个小的目标,持续开发,最终打造可复用类库
    • 继承树
      • 所有类都继承自Object,规范堆对象创建时的行为
    • 只抛异常,不处理异常
      • 使用THROW_EXCEPTION抛出异常,提高可移植性
    • 弱耦合性
      • 尽量不使用标准库中的类和函数,提高可移植性

    5、第一阶段学习总结

    • 数据结构算法之间的关系
    • 算法效率的度量方法
    • DTLib的基础设施构建
      • 顶层父类
      • 智能指针
      • 异常类
  • 相关阅读:
    LLVM之父Chris Lattner:编译器的黄金时代
    JAVA集合框架工具类自定义Collections集合方法
    linux(ARM)架构下的mysql安装使用(完整版)
    2-8:Http响应头content-type内容详解
    以太网转RS485串口计数器WiFI模块 LED灯光控制器IBF165
    2.3 为何使用Pthreads
    开源项目在线化 中文繁简体转换/敏感词/拼音/分词/汉字相似度/markdown 目录
    连锁超市如何部署远程监控系统
    在react中使用event(事件对象),如何使用,注意事项和react中如何定义和使用函数?
    Linux-查询目录下包含的目录数或文件数
  • 原文地址:https://blog.csdn.net/qq_38426928/article/details/125455461