用类模板做的智能指针
2015-12-26 13:38
239 查看
前言
做一个类模板的准备工作.先准备一个普通类, 她的关联类都调试过.
将准备改到类模板的类声明为template<typename T>, 一个类模板放在一个.h中
加入关联类的前向声明
在类模板中加入友元类模板的声明
为了维护方便, 将所有类实现都内联实现. 不要再放到类外部, 防止该类模板进行类特例时, 看的眼花~
测试代码
// SmartPtrD.cpp : Defines the entry point for the console application. // * 运用智能指针改写MyString #include "stdafx.h" #include "MyString.h" #include "SmartPtr.h" void fnTestTemplateSmartPtr(); void fnTestOnlyMyString(); int main(int argc, char* argv[]) { // fnTestOnlyMyString(); fnTestTemplateSmartPtr(); /** run result ISmartPtrElement::ISmartPtrElement()00333CA8, m_pOwner = 00333C50 CSmartPtr::CSmartPtr()0018FED8, m_pPtr = 00333CA8 ISmartPtrElement::ISmartPtrElement()00333E40, m_pOwner = 00333F18 CSmartPtr::CSmartPtr()0018FED0, m_pPtr = 00333E40 ISmartPtrElement::~ISmartPtrElement()00333CA8 inline CSmartPtr& operator = (const CSmartPtr& obj)0018FED8, m_pPtr = 00333E40 CMyString::fnTest CMyString::fnTest CMyString::fnTest CMyString::fnTest ptr = 0x00333F18 ptr + 1 = 0x00333F28 CSmartPtr::~CSmartPtr()0018FED0, m_pPtr = 00333E40 CSmartPtr::~CSmartPtr()0018FED8, m_pPtr = 00333E40 ISmartPtrElement::~ISmartPtrElement()00333E40 */ cout << "END, press any key to quit" << endl; _getch(); return 0; } void fnTestTemplateSmartPtr() { CMyString* pMyString = new CMyString; CMyString** ppMyString = NULL; _ASSERT(NULL != pMyString); CSmartPtr<CMyString> ptr = pMyString; CSmartPtr<CMyString> ptr2 = new CMyString; size_t nSize = sizeof(CMyString); typedef union un_tmp { size_t nAddr; CMyString* pClass; }UN_TMP; UN_TMP addr; /// 模拟指针操作 = ptr = ptr2; /// 模拟指针操作 -> ptr->fnTest(); /// 模拟指针操作 * (*ptr).fnTest(); /// 模拟指针操作 & ppMyString = &ptr; (*ppMyString)->fnTest(); (*(&ptr))->fnTest(); /// 打印智能指针中存储的对象指针之值 addr.pClass = *(&ptr); cout << "ptr = 0x" << std::hex << setiosflags(ios::uppercase) << setfill('0') << setw(8) << addr.nAddr << endl; /// 模拟指针操作 + addr.pClass = ptr + 1; ///< 只是计算地址, 不会报错^_^ cout << "ptr + 1 = 0x" << std::hex << setiosflags(ios::uppercase) << setfill('0') << setw(8) << addr.nAddr << endl; } void fnTestOnlyMyString() { CMyString* pstr1 = new CMyString("Hello"); SAFE_DELETE(pstr1); }
common.h
/// @file common.h /// @brief 公用头文件 #ifndef COMMON_H_1460AB26_69BA_45E7_8E75_3867BF8DA316 #define COMMON_H_1460AB26_69BA_45E7_8E75_3867BF8DA316 #include <iostream> #include <limits> #include <string> #include <crtdbg.h> #include <stdlib.h> #include <stdio.h> #include <stddef.h> #include <stdarg.h> #include <conio.h> #include <iomanip> using namespace std; #ifndef BOOL #define BOOL int #define TRUE 1 #define FALSE 0 #endif // #ifndef BOOL #ifndef NULL #define NULL 0 #endif // #ifndef NULL #ifndef SAFE_DELETE #define SAFE_DELETE(x) \ { \ if (NULL != (x)) \ { \ delete (x); \ (x) = NULL; \ } \ } #endif // #ifndef SAFE_DELETE #ifndef SAFE_DELETE_ARY #define SAFE_DELETE_ARY(x) \ { \ if (NULL != (x)) \ { \ delete[] (x); \ (x) = NULL; \ } \ } #endif // #ifndef SAFE_DELETE_ARY #endif // #ifndef COMMON_H_1460AB26_69BA_45E7_8E75_3867BF8DA316
ISmartPtrElement.h
// ISmartPtrElement.h: interface for the ISmartPtrElement class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_ISMARTPTRELEMENT_H__55DFBE74_2052_48E8_9CD6_9FD1567E61C3__INCLUDED_) #define AFX_ISMARTPTRELEMENT_H__55DFBE74_2052_48E8_9CD6_9FD1567E61C3__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "common.h" #include "MyString.h" #include "SmartPtr.h" /// ---------------------------------------- /// >> class ISmartPtrElement 普通实现 /// ---------------------------------------- /// 模板类的前向声明 template<typename T> class CSmartPtr; /// 抽象类, CSmartPtr中操作的元素类型 template<typename T> class ISmartPtrElement { friend class CSmartPtr<T>; ///< 声明另外一个模板类为友元 public: ISmartPtrElement(T* pOwner) :m_iRefCount(0) ,m_pOwner(NULL) { _ASSERT(NULL != pOwner); m_pOwner = pOwner; cout << "ISmartPtrElement::ISmartPtrElement()" << std::hex << setiosflags(ios::uppercase) << setfill('0') << setw(8) << (size_t)this << ", m_pOwner = " << std::hex << setiosflags(ios::uppercase) << setfill('0') << setw(8) << (size_t)m_pOwner << endl; } virtual ~ISmartPtrElement() { cout << "ISmartPtrElement::~ISmartPtrElement()" << std::hex << setiosflags(ios::uppercase) << setfill('0') << setw(8) << (size_t)this << endl; } void AddRef() {m_iRefCount++;} int Release() { if (m_iRefCount <= 0) { return 0; } if (--m_iRefCount == 0) { SAFE_DELETE(m_pOwner); } return m_iRefCount; } private: int m_iRefCount; ///< 参考计数 T* m_pOwner; ///< 所有者 }; /// ---------------------------------------- /// << class ISmartPtrElement 普通实现 /// ---------------------------------------- #endif // !defined(AFX_ISMARTPTRELEMENT_H__55DFBE74_2052_48E8_9CD6_9FD1567E61C3__INCLUDED_)
MyString.h
// MyString.h: interface for the CMyString class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_MYSTRING_H__3946972C_1380_4373_91E6_0C3BFDFEEED6__INCLUDED_) #define AFX_MYSTRING_H__3946972C_1380_4373_91E6_0C3BFDFEEED6__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "common.h" class CMyString { /// 构造函数, 析构函数, 拷贝构造函数 public: CMyString(); CMyString(const char* psrc); virtual ~CMyString(); CMyString(CMyString& src); CMyString(CMyString* psrc); /// 转换运算符重载 /// 运算符重载 void operator = (const char* pSrc); CMyString operator + (const char* pSrc); CMyString& operator += (const char* pSrc); bool operator > (const char* pSrc); bool operator >= (const char* pSrc); bool operator < (const char* pSrc); bool operator <= (const char* pSrc); bool operator == (const char* pSrc); bool operator != (const char* pSrc); const char* operator [] (size_t nIndex) const; /// 成员方法 const char* c_str() const; const char* StringFormatV(char* szFormat, ...); /// 测试用的方法, 就是为了打印点东西, 刷存在感 void fnTest() { cout << "CMyString::fnTest" << endl; } private: virtual CMyString* strcat(const char* pSrc); void setString(const char* pSrc); CMyString* strcpy(const char* pSrc); int compare(const char* pSrc); void init(); void uninit(); // member data private: char* m_lpString; ///< 开辟(new)的字符串缓冲区 int m_nLen; ///< 字符串长度 /// 如果最终要操作的字符串比缓冲区小, 就不用另外再开辟缓冲区了 int m_nSpaceLen; ///< 缓冲区总长度 }; ostream& operator<< (ostream& cout, CMyString& right); #endif // !defined(AFX_MYSTRING_H__3946972C_1380_4373_91E6_0C3BFDFEEED6__INCLUDED_)
SmartPtr.h
// SmartPtr.h: interface for the CSmartPtr class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_SMARTPTR_H__99AE9DED_C11E_47ED_927E_E7A058B8E9FC__INCLUDED_) #define AFX_SMARTPTR_H__99AE9DED_C11E_47ED_927E_E7A058B8E9FC__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "common.h" #include "ISmartPtrElement.h" ///---------------------------------------- /// >> class CSmartPtr 普通实现 ///---------------------------------------- /// 模板类的前向声明 template<typename T> class ISmartPtrElement; template<typename T> class CSmartPtr { public: CSmartPtr(T * pElement) :m_pPtr(NULL) { if (NULL != pElement) { m_pPtr = new ISmartPtrElement<T>(pElement); _ASSERT(NULL != m_pPtr); m_pPtr->AddRef(); } cout << "CSmartPtr::CSmartPtr()" << std::hex << setiosflags(ios::uppercase) << setfill('0') << setw(8) << (int)this << ", m_pPtr = " << std::hex << setiosflags(ios::uppercase) << setfill('0') << setw(8) << (int)m_pPtr << endl; } virtual ~CSmartPtr() { cout << "CSmartPtr::~CSmartPtr()" << std::hex << setiosflags(ios::uppercase) << setfill('0') << setw(8) << (int)this << ", m_pPtr = " << std::hex << setiosflags(ios::uppercase) << setfill('0') << setw(8) << (int)m_pPtr << endl; if (NULL != m_pPtr) { if (0 == m_pPtr->Release()) { SAFE_DELETE(m_pPtr); } } } /// 运算符重载 /// 重载常用的指针操作 inline CSmartPtr& operator = (const CSmartPtr& obj) { if (m_pPtr == obj.m_pPtr) { return *this; } if (NULL != m_pPtr) { if (0 == m_pPtr->Release()) { SAFE_DELETE(m_pPtr); } } m_pPtr = obj.m_pPtr; if (NULL != m_pPtr) { cout << "inline CSmartPtr& operator = (const CSmartPtr& obj)" << std::hex << setiosflags(ios::uppercase) << setfill('0') << setw(8) << (int)this << ", m_pPtr = " << std::hex << setiosflags(ios::uppercase) << setfill('0') << setw(8) << (int)m_pPtr << endl; m_pPtr->AddRef(); } return *this; } inline T* operator ->() { return m_pPtr->m_pOwner; } inline T operator *() { return *m_pPtr->m_pOwner; } inline T** operator &() { return &m_pPtr->m_pOwner; } inline T* operator +(size_t nOffset) { return (m_pPtr->m_pOwner + nOffset); } private: ISmartPtrElement<T>* m_pPtr; }; ///---------------------------------------- /// << class CSmartPtr 普通实现 ///---------------------------------------- #endif // !defined(AFX_SMARTPTR_H__99AE9DED_C11E_47ED_927E_E7A058B8E9FC__INCLUDED_)
MyString.cpp
// MyString.cpp: implementation of the CMyString class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MyString.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CMyString::CMyString() { init(); } CMyString::~CMyString() { uninit(); } CMyString::CMyString(CMyString& src) { init(); this->strcpy(src.c_str()); } CMyString::CMyString(CMyString* psrc) { init(); if (NULL != psrc) { this->strcpy(psrc->c_str()); } } CMyString::CMyString(const char* psrc) { init(); if (NULL != psrc) { this->strcpy(psrc); } } void CMyString::operator = (const char* pSrc) { strcpy(pSrc); } CMyString CMyString::operator + (const char* pSrc) { CMyString tmp; tmp = *this; tmp += pSrc; return tmp; } CMyString& CMyString::operator += (const char* pSrc) { strcat(pSrc); return *this; } const char* CMyString::operator [] (size_t nIndex) const { char* pRc = ""; if ((NULL != m_lpString) && (nIndex >= 0) && (nIndex < strlen(m_lpString))) { pRc = m_lpString + nIndex; } return pRc; } int CMyString::compare(const char* pSrc) { int iRc = 0; const char * pMe = (NULL != m_lpString) ? m_lpString : ""; const char * pSrcCpy = (NULL != pSrc) ? pSrc : ""; /// strcmp入参为空指针会报错 iRc = ::strcmp(pMe, pSrcCpy); return iRc; } bool CMyString::operator > (const char* pSrc) { return (compare(pSrc) > 0); } bool CMyString::operator >= (const char* pSrc) { return (compare(pSrc) >= 0); } bool CMyString::operator < (const char* pSrc) { return (compare(pSrc) < 0); } bool CMyString::operator <= (const char* pSrc) { return (compare(pSrc) <= 0); } bool CMyString::operator == (const char* pSrc) { return (compare(pSrc) == 0); } bool CMyString::operator != (const char* pSrc) { return (compare(pSrc) != 0); } void CMyString::init() { m_lpString = NULL; m_nLen = 0; m_nSpaceLen = 0; } void CMyString::uninit() { SAFE_DELETE_ARY(m_lpString); m_nLen = 0; m_nSpaceLen = 0; } void CMyString::setString(const char* pSrc) { this->strcpy(pSrc); } const char* CMyString::c_str() const { if (NULL == m_lpString) { return ""; } else { return m_lpString; } } CMyString* CMyString::strcpy(const char* pSrc) { int iLenNew = 0; char* pNewString = NULL; if (NULL == pSrc) { return this; } iLenNew = ::strlen(pSrc); if (iLenNew > (m_nSpaceLen - 1)) { pNewString = new char[iLenNew + 1]; _ASSERT(NULL != pNewString); pNewString[0] = '\0'; ::strcpy(pNewString, pSrc); SAFE_DELETE_ARY(m_lpString); m_nLen = iLenNew; m_nSpaceLen = m_nLen + 1; m_lpString = pNewString; } else { m_nLen = strlen(pSrc); _ASSERT(NULL != m_lpString); if (0 != ::strcmp(m_lpString, pSrc)) { ::strcpy(m_lpString, pSrc); } } return this; } CMyString* CMyString::strcat(const char* pSrc) { int iLenNew = 0; char* pNewString = NULL; if (NULL == pSrc) { return this; } if (NULL == m_lpString) { this->strcpy(pSrc); return this; } iLenNew = m_nLen + strlen(pSrc); if (iLenNew > (m_nSpaceLen - 1)) { pNewString = new char[iLenNew + 1]; pNewString[0] = '\0'; ::strcpy(pNewString, m_lpString); SAFE_DELETE_ARY(m_lpString); ::strcat(pNewString, pSrc); m_nLen = iLenNew; m_nSpaceLen = m_nLen + 1; m_lpString = pNewString; } else { m_nLen += strlen(pSrc); ::strcat(m_lpString, pSrc); } return this; } const char* CMyString::StringFormatV(char* szFormat, ...) { size_t nStrLen = 1024 * 100; ///< 默认开100K空间 va_list args; char* pNewString = NULL; va_start(args, szFormat); /** _MSC_VER Defines the compiler version. Defined as 1200 for Microsoft Visual C++ 6.0. Always defined. */ if (_MSC_VER > 1200) { /// vs6不允许这么用, vs2010可以 /// 估算需要的缓冲区长度 nStrLen = _vsnprintf(NULL, 0, szFormat, args); } pNewString = new char[nStrLen + 1]; _ASSERT(pNewString); ::memset(pNewString, 0, (nStrLen + 1) * sizeof(char)); nStrLen = _vsnprintf(pNewString, nStrLen, szFormat, args); va_end(args); this->strcpy(pNewString); return this->c_str(); } ostream& operator<< (ostream& cout, CMyString& right) { cout << right.c_str(); return cout; }
相关文章推荐
- 第四章(数组) 编程题 1
- window7下安装第三方包报错及解决
- LINUX下安装U-MAIL邮件系统
- 第8次作业总结
- crm使用soap分配记录
- 2015总结
- Lock-Free
- 马哥linux学习笔记:源码编译安装
- Mysql for Excel安装
- iOS UIWebView 载入https 网站出现NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL,
- 如何求两个文件的交集、并集和差集?------sort和uniq闪亮登场
- Task Schedule
- 添加PATH
- 黑马程序员——java基础之面向对象
- [mysql for excel指南] 第一章 介绍
- 关于中文编程是解决中国程序员效率的秘密武器的问题思考
- 程序员能力培养
- 图片加载
- Mbps MB/S Mb/s
- LeetCode Search a 2D Matrix