DTLib基础建设(智能指针类、异常类,顶层父类)

 学习狄泰软件数据结构笔记

智能指针 

 DTLib基础建设(智能指针类、异常类,顶层父类)_第1张图片

 DTLib基础建设(智能指针类、异常类,顶层父类)_第2张图片

 SmartPointer.h

#ifndef SMARTPOINTER_H
#define SMARTPOINTER_H

/*智能指针
* 指针生命周期结束时主动释放堆空间
* 一片堆空间只能由一个指针标识
* 杜绝指针运算和比较
* 最大程度避免内存问题
*/

namespace DTLib
{

template 
class SmartPorter
{
protected:
	T* m_pointer;

public:
	SmartPorter(T* p = NULL)
	{
		m_pointer = p;
	}

	SmartPorter(const SmartPorter& obj)
	{
		m_pointer = obj.m_pointer;
		//把对象const属性去掉,一片堆空间只能由一个指针标识
		const_cast&>(obj).m_pointer = NULL;
	}

	SmartPorter& operator= (const SmartPorter& obj)
	{
		if (this != &obj)
		{
			delete m_pointer;
			m_pointer = obj.m_pointer;
			//写的时候忘记写.m_pointer
			const_cast&> (obj).m_pointer = NULL;
			return *this;
		}
	}


	T* operator-> ()
	{
		return m_pointer;
	}
	T& operator* ()
	{
		return *m_pointer;
	}
	bool isNull()
	{
		return (m_pointer == NULL);
	}
	~SmartPorter()
	{
		delete m_pointer;
	}

};

}


#endif

测试main.cpp

#include 
#include "SmartPointer.h"

/*
*问题1:拷贝构造函数
*/

using namespace std;
using namespace DTLib;

class Test
{
public:
	Test()
	{
		cout << "test()" << endl;
	}
	~Test()
	{
		cout << "~test()" << endl;
	}
};

int main()
{
	SmartPorter sp = new Test();
	/**
	*-- > SmartPorter(T * p = NULL) -->nsp = sp;然后运行=重载-->operator=  
	* return 前运行跳转~SmartPorter()-->跳转~Test()-->在执行~SmartPorter()的
	* delete m_pointer;
	*/
	SmartPorter nsp;
	nsp = sp;

	cout << sp.isNull() << endl;
	cout << nsp.isNull() << endl;
	return 0;
}

 测试结果

 

 异常DTLib基础建设(智能指针类、异常类,顶层父类)_第3张图片

DTLib基础建设(智能指针类、异常类,顶层父类)_第4张图片

DTLib基础建设(智能指针类、异常类,顶层父类)_第5张图片

DTLib基础建设(智能指针类、异常类,顶层父类)_第6张图片

DTLib基础建设(智能指针类、异常类,顶层父类)_第7张图片

DTLib基础建设(智能指针类、异常类,顶层父类)_第8张图片

 DTLib基础建设(智能指针类、异常类,顶层父类)_第9张图片

DTLib基础建设(智能指针类、异常类,顶层父类)_第10张图片 DTLib基础建设(智能指针类、异常类,顶层父类)_第11张图片

 excrption.h

#ifndef __EXCEPTION_H
#define __EXCEPTION_H

namespace DTLib
{
#define THROW_EXCEPTION(e,m)	(throw e(m,__FILE__,__LINE__)) 

class Exception
{
protected:
	char* m_message;//异常信息
	char* m_location;//异常源

	void init(const char* message, const char* file, int line);
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;

	//代表Exception类为纯虚函数,子类必须提供实现
	//Exception类不能生成对象,所以测试时把=0去掉
	virtual ~Exception() = 0;
};

}

exception.cpp 

#include 
#include 
#include "Exception.h"
//#pragma warning(disable:4996)

using namespace DTLib;
using namespace std;
void Exception::init(const char* message, const char* file, int line)
{
	//把message拷贝到堆空间
	m_message = strdup(message);
	if (file != NULL)
	{
		char sl[16] = { 0 };
		itoa(line, sl, 10);//把int 按10进制转换为字符
		//+2的原因 ’:‘冒号和字符串结束符’\n‘
		m_location = static_cast(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 = NULL;
	}
}

Exception::Exception(const char* message)
{
	init(message, NULL, 0);
}
Exception::Exception(const char* file, int line)
{
	init(NULL, file, line);
}
Exception::Exception(const char* message, const char* file, int line)
{
	init(message, file, line);
}

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()
{
	free(m_message);
	free(m_location);
}

 改写DTLib基础建设(智能指针类、异常类,顶层父类)_第12张图片

如果m_location分配内存失败 


		if (m_location != NULL)
		{
			m_location = strcpy(m_location, file);
			//字符串拼接
			m_location = strcat(m_location, ":");
			m_location = strcat(m_location, sl);
		}
		else
		{
			/*
			//不能这么写
			//从高层次看:父类还没创建就抛出子类异常
			//从代码运行看:死循环
			//NoEnoughMemoryException调用Exception(message)构造函数--条用init()及当前函数
			//之后又malloc返回一个空值,又抛出当前异常,反复循环
			THROW_EXCEPTION(NoEnoughMemoryException, "Exception::init");
			*/
			m_location = NULL;
		}
	}
	else
	{
		m_location = NULL;
	}

 测试main.cpp

#include 
#include"Exception.h"

using namespace std;
using namespace DTLib;
int main()
{
	try
	{
		THROW_EXCEPTION(Exception,"test");
	}
	catch (const Exception& e)
	{
		cout << "catch(const Exception& e)" << endl;
		cout << e.message() << endl;
		cout << e.location() << endl;
	}
	return 0;
}

virtual ~Exception() = 0;时

 DTLib基础建设(智能指针类、异常类,顶层父类)_第13张图片

 

异常类

exception.h

//计算异常子类
class ArithemticException :public Exception
{
public:
	//构造函数
	ArithemticException() :Exception(NULL) {}
	ArithemticException(const char* message) :Exception(message){}
	ArithemticException(const char* file, int line) :Exception(file, line){}
	ArithemticException(const char* message, const char* file, int line) : Exception(message, file, line){}

	//拷贝构造
	ArithemticException(const ArithemticException& e) :Exception(e) {}

	ArithemticException& operator= (const ArithemticException& e)
	{
		Exception::operator= (e);
		return *this;
	}
};

//空指针异常
class NullPointerException : public Exception
{
public:
    NullPointerException() : Exception(0) { }
    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;
    }
};

//越界异常
class IndexOutOfBoundsException : public Exception
{
public:
    IndexOutOfBoundsException() : Exception(0) { }
    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;
    }
};

//内存不足异常
class NoEnoughMemoryException : public Exception
{
public:
    NoEnoughMemoryException() : Exception(0) { }
    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;
    }
};

//参数错误异常
class InvalidParameterException : public Exception
{
public:
    InvalidParameterException() : Exception(0) { }
    InvalidParameterException(const char* message) : Exception(message) { }
    InvalidParameterException(const char* file, int line) : Exception(file, line) { }
    InvalidParameterException(const char* message, const char* file, int line) : Exception(message, file, line) { }

    InvalidParameterException(const InvalidParameterException& e) : Exception(e) { }

    InvalidParameterException& operator= (const InvalidParameterException& e)
    {
        Exception::operator=(e);

        return *this;
    }
};

class InvalidOperationException : public Exception
{
public:
    InvalidOperationException() : Exception(0) { }
    InvalidOperationException(const char* message) : Exception(message) { }
    InvalidOperationException(const char* file, int line) : Exception(file, line) { }
    InvalidOperationException(const char* message, const char* file, int line) : Exception(message, file, line) { }

    InvalidOperationException(const InvalidOperationException& e) : Exception(e) { }

    InvalidOperationException& operator= (const InvalidOperationException& e)
    {
        Exception::operator=(e);

        return *this;
    }
};

测试main.cpp

int main()
{
	try
	{
		THROW_EXCEPTION(ArithemticException,"test");
	}
/*
	catch (const ArithemticException& e)
	{
		cout << "catch(const ArithemticException& e)" << endl;
		cout << e.message() << endl;
		cout << e.location() << endl;
	}
*/

	//子类对象可以出现在任何父类对象需要的地方
	//不许要类型转换,一个子类对象 = 父类对象
	catch (const Exception& e)
	{
		cout << "catch(const Exception& e)" << endl;
		cout << e.message() << endl;
		cout << e.location() << endl;
	}

	/*
	//捕捉不到异常
	//子类需要放到父类前面
	catch (const ArithemticException& e)
	{
		cout << "catch(const ArithemticException& e)" << endl;
		cout << e.message() << endl;
		cout << e.location() << endl;
	}
	*/
	return 0;
}

 顶成父类创建

DTLib基础建设(智能指针类、异常类,顶层父类)_第14张图片

 不提供编译器默认new的行为,自定义行为

DTLib基础建设(智能指针类、异常类,顶层父类)_第15张图片

 Object.h

#ifndef		__OBJIET_H
#define		__OBJIET_H

namespace DTLib {

	class Object
	{
	public:
		//throw 异常规格说明,不会抛出任何异常
		//如new失败,返回空
		void* operator new (unsigned int size) throw();
		void operator delete (void* p);
		void* operator new[] (unsigned int size) throw();
		void operator delete[](void* p);
		virtual ~Object() = 0;
	};
}
#endif // !__OBJIET_H

  Object.cpp

#include 
#include 
#include "Object.h"

using namespace DTLib;
using namespace std;

void* Object::operator new (unsigned int size) throw()
{
	cout << "Object::operator new: "<< size << endl;
	return malloc(size);
}
void Object::operator delete (void* p)
{
	cout << "Object::operator delete: " << p << endl;
	free(p);
}
//new失败不会抛异常,return返回空
void* Object::operator new[](unsigned int size) throw()
{
	cout << "operator new[]: " << size << endl;
	return malloc(size);
}
void Object::operator delete[](void* p)
{
	cout << "operator delete[]: "<< p << endl;
	free(p);
}
Object::~Object()
{

}

测试main.cpp

#include 
//#include "SmartPointer.h"
//#include"Exception.h"
#include"Object.h"
/*
*问题1:拷贝构造函数
*/

using namespace std;
using namespace DTLib;

class Test : public Object
{
public:
	int i;
	int j;
};

class Child : public Test
{
public:
	int k;
};

int main()
{
	Object* obj1 = new Test();
	Object* obj2 = new Child();

	cout << "obj1: " << obj1 << endl;
	cout << "obj2: " << obj2 << endl;

	delete obj1;
	delete obj2;

	return 0;
}

 DTLib基础建设(智能指针类、异常类,顶层父类)_第16张图片

DTLib基础建设(智能指针类、异常类,顶层父类)_第17张图片

DTLib基础建设(智能指针类、异常类,顶层父类)_第18张图片

 DTLib基础建设(智能指针类、异常类,顶层父类)_第19张图片

继承Object类 

 

 

 测试智能指针main.cpp

int main()
{
	SmartPorter* sp = new SmartPorter();
	delete sp;

	return 0;
}

 object.cpp打断点

DTLib基础建设(智能指针类、异常类,顶层父类)_第20张图片

测试成功 

 

 异常

DTLib基础建设(智能指针类、异常类,顶层父类)_第21张图片

 

 DTLib基础建设(智能指针类、异常类,顶层父类)_第22张图片

你可能感兴趣的:(DTLib数据结构,数据结构,c++)