C++细节笔记13

模拟智能指针的行为

#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);
}

(完)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值