模拟智能指针的行为
#include <iostream>
#include <cstdlib>
using namespace std;
class CFoo
{
public:
CFoo()
{
cout << "CFoo构造函数调用" << endl;
}
~CFoo()
{
cout << "CFoo析构函数调用" << endl;
}
void Test()
{
cout << "CFoo的Test函数被调用" << endl;
}
private:
};
class CSmartPtr
{
public:
// 无参构造
CSmartPtr() : m_pCFoo(nullptr)
{
m_pnRefCnt = new size_t(0);
}
// 含参构造
explicit CSmartPtr(CFoo* pCFoo) : m_pCFoo(pCFoo)
{
size_t nCnt = 0;
if (nullptr != pCFoo)
{
nCnt = 1;
}
m_pnRefCnt = new size_t(nCnt);
}
// 拷贝构造
CSmartPtr(const CSmartPtr &obj)
{
m_pCFoo = obj.m_pCFoo;
m_pnRefCnt = obj.m_pnRefCnt;
++(*m_pnRefCnt);
}
// 赋值运算符重载
CSmartPtr& operator=(const CSmartPtr& obj)
{
// 检查自身引用计数并确定是否释放等操作
if ((nullptr != m_pnRefCnt) && (*m_pnRefCnt > 1))
{
// 自身引用计数>1的情况下降低自身引用计数
--(*m_pnRefCnt);
}
else
{
// 自身引用计数<=1的情况下,执行析构原对象的操作
this->~CSmartPtr();
}
// 增加目标引用计数
m_pCFoo = obj.m_pCFoo;
m_pnRefCnt = obj.m_pnRefCnt;
++(*m_pnRefCnt);
return(*this);
}
// 析构函数
~CSmartPtr()
{
if (nullptr != m_pCFoo)
{
// 存在引用计数并且至少有2个对象正在引用
if ((nullptr != m_pnRefCnt) && (*m_pnRefCnt > 1))
{
--(*m_pnRefCnt);
}
// 最多只有1个对象正在引用,执行析构操作
else
{
delete m_pCFoo;
m_pCFoo = nullptr;
if (nullptr != m_pnRefCnt)
{
// 释放引用计数空间内存
delete m_pnRefCnt;
m_pnRefCnt = nullptr;
}
}
}
else
{
if (nullptr != m_pnRefCnt)
{
// 释放引用计数空间内存
delete m_pnRefCnt;
m_pnRefCnt = nullptr;
}
}
}
// 运算符重载
CFoo* operator->()
{
return(m_pCFoo);
}
CFoo& operator*()
{
return(*m_pCFoo);
}
CFoo& operator[](size_t nIdx)
{
return(m_pCFoo[nIdx]);
}
bool operator==(const CSmartPtr &ptr)
{
return(*this == ptr);
}
bool operator!=(const CSmartPtr &ptr)
{
return(*this != ptr);
}
private:
CFoo* m_pCFoo;
size_t* m_pnRefCnt;
};
int main()
{
CFoo* pNewCFoo = new CFoo;
CSmartPtr CSmrtPtrObj(new CFoo);
CSmartPtr CSmrtPtrObj1(pNewCFoo);
// CSmrtPtrObj.GetCFoo()->Test();
CSmrtPtrObj1 = CSmrtPtrObj;
CSmrtPtrObj->Test();
(*CSmrtPtrObj).Test();
system("pause");
return(0);
}
异常的使用例子:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
class CException
{
public:
CException()
: m_strFileName("null"), m_nLineNum(0), m_strErrInfo("null")
{
}
CException(string strFileName, size_t nLineNum, string strErrInfo)
: m_strFileName(strFileName), m_nLineNum(nLineNum), m_strErrInfo(strErrInfo)
{
}
virtual void reason() const
{
char szErrInfo[256] = { 0 };
cout << "CException类: " << endl;
sprintf(szErrInfo, "%s: %lld行 %s", m_strFileName.c_str(), m_nLineNum, m_strErrInfo.c_str());
cout << szErrInfo << endl;
}
protected:
string m_strFileName;
size_t m_nLineNum;
string m_strErrInfo;
};
class CAnimalException : public CException
{
public:
CAnimalException(string strErrInfo = "动物的身高或体重没写") : CException(__FILE__, __LINE__, strErrInfo)
{
}
CAnimalException(string strFileName, size_t nLineNum, string strErrInfo = "动物的身高或体重没写")
: CException(strFileName, nLineNum, strErrInfo)
{
}
virtual void reason() const
{
char szErrInfo[256] = { 0 };
cout << "CAnimalException类: " << endl;
sprintf(szErrInfo, "%s: %lld行 %s", m_strFileName.c_str(), m_nLineNum, m_strErrInfo.c_str());
cout << szErrInfo << endl;
}
private:
};
class Animal
{
public:
Animal()
: m_DblHeight(0.0), m_DblKilo(0.0)
{
}
Animal(double DblHeight, double DblKilo)
: m_DblHeight(DblHeight), m_DblKilo(DblKilo)
{
}
void SetHeight(double dblHeight)
{
if (dblHeight >= 0.0)
{
m_DblHeight = dblHeight;
}
}
void SetKilo(double dblKilo)
{
if (dblKilo >= 0.0)
{
m_DblKilo = dblKilo;
}
}
void ShowAnimalInfo()
{
if ((0.0 == m_DblKilo) || (0.0 == m_DblHeight))
{
throw CAnimalException();
}
else
{
cout << "身高: " << m_DblHeight << " 体重: " << m_DblKilo << endl;
}
}
private:
double m_DblHeight;
double m_DblKilo;
};
class CTriAngleException : public CException
{
public:
CTriAngleException(string strErrInfo = "边长为0动物的身高或体重没写") : CException(__FILE__, __LINE__, strErrInfo)
{
}
CTriAngleException(string strFileName, size_t nLineNum, string strErrInfo = "动物的身高或体重没写")
: CException(strFileName, nLineNum, strErrInfo)
{
}
virtual void reason() const
{
char szErrInfo[256] = { 0 };
cout << "CTriAngleException类: " << endl;
sprintf(szErrInfo, "%s: %lld行 %s", m_strFileName.c_str(), m_nLineNum, m_strErrInfo.c_str());
cout << szErrInfo << endl;
}
};
class CTriAngle
{
public:
CTriAngle() : m_uiArc0(0), m_uiArc1(0), m_uiArc2(0)
{
}
CTriAngle(unsigned int uiArc0, unsigned int uiArc1, unsigned int uiArc2) :
m_uiArc0(uiArc0), m_uiArc1(uiArc1), m_uiArc2(uiArc2)
{
}
void ShowArcs()
{
if ((0 == m_uiArc0) || (0 == m_uiArc1) || (0 == m_uiArc2))
{
throw(CTriAngleException("三角形边有出现长度为0"));
}
else if (((m_uiArc0 + m_uiArc1) < m_uiArc2) ||
((m_uiArc1 + m_uiArc2) < m_uiArc0) ||
((m_uiArc2 + m_uiArc0) < m_uiArc1))
{
throw(CTriAngleException("三角形边两边和不大于第三边"));
}
}
private:
// 三角形三条边
unsigned int m_uiArc0;
unsigned int m_uiArc1;
unsigned int m_uiArc2;
};
void func1()
{
Animal ani;
ani.ShowAnimalInfo();
}
void func2()
{
CTriAngle tri(5, 2, 1);
tri.ShowArcs();
}
int main()
{
try
{
func2();
}
catch (CException& e)
{
e.reason();
}
catch (...)
{
cout << "其他异常捕获" << endl;
}
system("pause");
return(0);
}
(完)