1 为什么有异常类族
在程序的逻辑处理的时候,会有一些异常的现象,这种情况,我们只能预测他可能出现,但是却无法彻底的避免,则就要在一些会出现异常的地方做些防御,一旦出现异常,就要有相应的处理对策。
2 异常类的构建
一个工程中,代码的逻辑是错综复杂,则就要有一定的章程来管理异常的处理,这样,可以帮助我们的程序看起来干净整洁。在现在的工程中,常见的异常一般有:
- 计算异常;例如做了除以0的操作
- 空指针异常:例如对空指针做了不合法的操作
- 访问越界异常
- 内存不足异常
- 参数错误异常
异常情况的整理与分类,我们可以看出,这些异常有一定的共性,但也有不同的地方。我们就利用C++语言语言的继承与多态的特性,做一个基础的异常类,然后各个类从基础类继承,然后自己添加自己的特性。
2.1 异常类的基类构建
2.1.1 提示函数
既然是异常的类,他的出现,就是为了告警,那么就会有一些提示信息,实际使用的使用,都是抛出异常的地方输入一些提示语句。那么构建类的时候,就要设计提示语句的输入的地方。
Exceptional(const char *message);
Exceptional(const char *file, int line);
Exceptional(const char *message, const char *file,const int line);
virtual const char *message() const;
virtual const char * location( ) const ;
从这三个构建函数的样子可以看出,基本是一样的,就是个别的参数没有而已,为了代码的复用,可以写一个公用的私有函数来做三个构建函数的实现。
void init(const char *message, const char *file, int line);
2.1.2 属性工能函数
既然是类,就要符合C++的类的一般共性,但是该类在 赋值操作的时候,或者拷贝构造的时候,就需要特殊处理,则需要对这两个工能做处理
Exceptional(const Exceptional& obj);
Exceptional& operator = ( const Exceptional& obj);
2.2 类的架构
以上的描述已经基本可以构造这个类了,但是有个细节要注意,就是在传入的字符串存储空间是无法确定的。为了防止意外,该类要对传入的字符串做一个复制,在函数被析构的时候,就要释放。所以类的构造如下。
class Exceptional
{
protected:
char* m_message=nullptr;
char* m_location =nullptr;
void init(const char *message, const char *file, int line);
public:
Exceptional(const char *message);
Exceptional(const char *file, int line);
Exceptional(const char *message, const char *file,const int line);
Exceptional(const Exceptional& obj);
Exceptional& operator = ( const Exceptional& obj);
virtual const char *message() const;
virtual const char * location( ) const ;
virtual ~Exceptional() =0 ;
};
3基类的实现
void Exceptional :: init(const char *message, const char *file, const int line)
{
//因为不能保证传进来的 message 的空间,所以复制一份存到堆中
m_message= strdup(message);
if(file != NULL)
{
char sl[16]={0};
itoa(line,sl,10);
m_location=reinterpret_cast< char * >(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=nullptr;
}
}
Exceptional :: Exceptional(const char *message)
{
init( message, NULL, NULL);
}
Exceptional :: Exceptional(const char *file, int line)
{
init( NULL, file, line);
}
Exceptional :: Exceptional( const char *message, const char *file,const int line)
{
init( message, file, line);
}
Exceptional :: Exceptional( const Exceptional& obj)
{
m_message= strdup(obj.m_message);
m_location= strdup(obj.m_location);
}
Exceptional& Exceptional :: operator = ( const Exceptional& obj)
{
if(this != &obj)
{
free(m_message);
free(m_location);
m_message= strdup(obj.m_message);
m_location= strdup(obj.m_location);
}
return *this;
}
const char * Exceptional :: message() const
{
return m_message;
}
const char * Exceptional :: location( ) const
{
return m_location;
}
Exceptional :: ~Exceptional()
{
free(m_message);
free(m_location);
}
4 继承类的实现
基类完成以后,剩下的就是对各自类的具体实现、
4.1 计算异常类的实现
/****************************************************
* class ArithmeticExcption 计算异常
****************************************************
* */
class ArithmeticExcption :public Exceptional
{
public:
ArithmeticExcption() : Exceptional(nullptr) {}
ArithmeticExcption(const char * message ) : Exceptional( message ) {}
ArithmeticExcption(const char *file, int line): Exceptional( file, line ) {}
ArithmeticExcption(const char *message, const char *file,const int line):Exceptional(message, file, line){}
ArithmeticExcption(const ArithmeticExcption & obj) : Exceptional(obj ){}
ArithmeticExcption& operator = (const ArithmeticExcption & obj)
{
Exceptional::operator = ( obj);
return *this ;
}
};
4.2 空指针异常
/****************************************************
* class NullPointerExcption 空指针异常
****************************************************
* */
class NullPointerExcption :public Exceptional
{
public:
NullPointerExcption() : Exceptional(nullptr) {}
NullPointerExcption(const char * message ) : Exceptional( message ) {}
NullPointerExcption(const char *file, int line): Exceptional( file, line ) {}
NullPointerExcption(const char *message, const char *file,const int line):Exceptional(message, file, line){}
NullPointerExcption(const NullPointerExcption & obj) : Exceptional(obj ){}
NullPointerExcption& operator = (const NullPointerExcption & obj)
{
Exceptional::operator = ( obj);
return *this ;
}
};
4.3 访问越界异常
/****************************************************
* class IndexOutOfBoundsException 访问越界异常
****************************************************
* */
class IndexOutOfBoundsException :public Exceptional
{
public:
IndexOutOfBoundsException() : Exceptional(nullptr) {}
IndexOutOfBoundsException(const char * message ) : Exceptional( message ) {}
IndexOutOfBoundsException(const char *file, int line): Exceptional( file, line ) {}
IndexOutOfBoundsException(const char *message, const char *file,const int line):Exceptional(message, file, line){}
IndexOutOfBoundsException(const IndexOutOfBoundsException & obj) : Exceptional(obj ){}
IndexOutOfBoundsException& operator = (const IndexOutOfBoundsException & obj)
{
Exceptional::operator = ( obj);
return *this ;
}
};
4.4 内存不足异常
/****************************************************
* class NoEnoughMemoryException 内存不足异常
****************************************************
* */
class NoEnoughMemoryException :public Exceptional
{
public:
NoEnoughMemoryException() : Exceptional(nullptr) {}
NoEnoughMemoryException(const char * message ) : Exceptional( message ) {}
NoEnoughMemoryException(const char *file, int line): Exceptional( file, line ) {}
NoEnoughMemoryException(const char *message, const char *file,const int line):Exceptional(message, file, line){}
NoEnoughMemoryException(const NoEnoughMemoryException & obj) : Exceptional(obj ){}
NoEnoughMemoryException& operator = (const NoEnoughMemoryException & obj)
{
Exceptional::operator = ( obj);
return *this ;
}
};
4.5 参数异常
/****************************************************
* class InvalidParameterExcetion 参数异常
****************************************************
* */
class InvalidParameterExcetion :public Exceptional
{
public:
InvalidParameterExcetion() : Exceptional(nullptr) {}
InvalidParameterExcetion(const char * message ) : Exceptional( message ) {}
InvalidParameterExcetion(const char *file, int line): Exceptional( file, line ) {}
InvalidParameterExcetion(const char *message, const char *file,const int line):Exceptional(message, file, line){}
InvalidParameterExcetion(const InvalidParameterExcetion & obj) : Exceptional(obj ){}
InvalidParameterExcetion& operator = (const InvalidParameterExcetion & obj)
{
Exceptional::operator = ( obj);
return *this ;
}
};
5 使用注意
类的父子兼容性原则,做catch 时,把子类写在前边。