学习狄泰软件数据结构笔记
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;
}
测试结果
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);
}
如果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;时
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;
}
不提供编译器默认new的行为,自定义行为
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;
}
继承Object类
测试智能指针main.cpp
int main()
{
SmartPorter* sp = new SmartPorter();
delete sp;
return 0;
}
object.cpp打断点
测试成功
异常