- DTLib 中的全部類位於單一的繼承樹
Exception 類繼承自 Object算法
- 堆空間中建立異常對象失敗時,返回NULL指針
新增 InvalidOperationException 異常類編程
- 成員函數調用時,若是狀態不正確則拋出異常
SmartPointer 類繼承自 Object 類數據結構
- 堆空間中建立智能指針對象失敗時,返回NULL指針
文件:SmartPointer.hide
#ifndef SMARTPOINTER_H #define SMARTPOINTER_H #include "Object.h" namespace DTLib { template<typename T> class SmartPointer : public Object // 修改 { public: SmartPointer(T *p = nullptr) { m_pointer = p; } SmartPointer(const SmartPointer &obj) { m_pointer = obj.m_pointer; const_cast<SmartPointer&>(obj).m_pointer = nullptr; } SmartPointer &operator= (const SmartPointer &obj) { if (this != &obj) { delete m_pointer; m_pointer = obj.m_pointer; const_cast<SmartPointer&>(obj).m_pointer = nullptr; } return *this; } T *operator-> () { return m_pointer; } T &operator* () { return *m_pointer; } bool isNull() { return (m_pointer == nullptr); } T *get() { return m_pointer; } ~SmartPointer() { delete m_pointer; } protected: T *m_pointer = nullptr; }; } #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 // 修改 { 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; protected: char *m_message = nullptr; char *m_location = nullptr; }; class ArithmeticExcption : public Exception { public: ArithmeticExcption() : Exception(nullptr) { } ArithmeticExcption(const char *message) : Exception(message) { } ArithmeticExcption(const char *file, int line) : Exception(file, line) { } ArithmeticExcption(const char *message, const char *file, int line) : Exception(message, file, line) { } ArithmeticExcption(const ArithmeticExcption &e) : Exception(e) { } ArithmeticExcption &operator= (const ArithmeticExcption &e) { Exception::operator=(e); return *this; } ~ArithmeticExcption() override { } }; class NullPointerException : public Exception { public: NullPointerException() : Exception(nullptr) { } 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; } ~NullPointerException() override { } }; class IndexOutOfBoundsException : public Exception { public: IndexOutOfBoundsException() : Exception(nullptr) { } 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; } ~IndexOutOfBoundsException() override { } }; class NoEnoughMemoryException : public Exception { public: NoEnoughMemoryException() : Exception(nullptr) { } 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; } ~NoEnoughMemoryException() override { } }; class InvalidParameterExcetion : public Exception { public: InvalidParameterExcetion() : Exception(nullptr) { } InvalidParameterExcetion(const char *message) : Exception(message) { } InvalidParameterExcetion(const char *file, int line) : Exception(file, line) { } InvalidParameterExcetion(const char *message, const char *file, int line) : Exception(message, file, line) { } InvalidParameterExcetion(const InvalidParameterExcetion &e) : Exception(e) { } InvalidParameterExcetion &operator= (const InvalidParameterExcetion &e) { Exception::operator=(e); return *this; } ~InvalidParameterExcetion() override { } }; class InvalidOpertionExcetion : public Exception // 增長 { public: InvalidOpertionExcetion() : Exception(nullptr) { } InvalidOpertionExcetion(const char *message) : Exception(message) { } InvalidOpertionExcetion(const char *file, int line) : Exception(file, line) { } InvalidOpertionExcetion(const char *message, const char *file, int line) : Exception(message, file, line) { } InvalidOpertionExcetion(const InvalidOpertionExcetion &e) : Exception(e) { } InvalidOpertionExcetion &operator= (const InvalidOpertionExcetion &e) { Exception::operator=(e); return *this; } ~InvalidOpertionExcetion() override { } }; } #endif // EXCEPTION_H
文件:Exception.cpp (未修改)學習
#include "Exception.h" #include <cstring> #include <cstdlib> namespace DTLib { Exception::Exception(const char *message) : Exception(message, nullptr, 0) { } Exception::Exception(const char *file, int line) : Exception(nullptr, file, line) { } Exception::Exception(const char *message, const char *file, int line) { m_message = strdup(message); if (file != nullptr) { char sl[16] = {0}; itoa(line, sl, 10); m_location = static_cast<char*>(malloc(strlen(file) + strlen(sl) + 2)); m_location = strcpy(m_location, file); m_location = strcat(m_location, ":"); m_location = strcat(m_location, sl); } else { m_location = nullptr; } } 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() { delete m_message; delete m_location; } }
DTLib 的開發方式和注意事項this
迭代開發spa
- 每次完成一個小的目標,持續開發,最終打造可複用類庫
單一繼承樹設計
- 全部類都繼承自 Object,規範堆對象建立時的行爲
只拋異常,不處理異常指針
- 使用 THROW_EXCEPTION 拋出異常,提升可移植性
弱耦合性
- 儘可能不使用標準庫中的類和函數,提升可移植性
說明1:只拋異常,不處理異常
背景:有公司會明確規定不容許使用異常處理機制(throw,try,catch)
解決方案:
#define THROW_EXCEPTION(e, m) //(throw e(m, __FILE__, __LINE__))
說明2:儘可能不使用標準庫中的內容
背景:有公司會明確規定不容許使用標準庫
解決方案:當前只在Object文件和Exception文件中使用了malloc,free, strlen, strdup等極少數庫函數,這是極其容易被替換的。
- 數據結構與算法之間的關係
- 算法效率的度量方法
DTLib 的基礎設施構建
- 頂層父類
- 智能指針
- 異常類
以上內容整理於狄泰軟件學院系列課程,請你們保護原創!