Ogre异常处理回顾

来源:互联网 发布:学会plc编程工资高吗 编辑:程序博客网 时间:2024/05/18 02:40

Ogre 异常处理

        Ogrec++内建的异常处理机制来处理错误

使用异常处理的好处

        首先,使用异常 处理了,可以使得C++程序的两个部分相互通信(这两个部分通常是分别开发的)。检测到异常的部分可以抛出异常,而另一部分可以捕获异常并做出处理。

        其次,使用异常处理,可以避免用返回值来定义错误,当有错误发生的时候,一个异常就会被抛出,这个异常里面封装了发生错误的详细信息。

Eg:

        Try{

                           app.go();

         }catcn(Ogre::Exception &e){

                                                       //处理异常

        }

首先,这段代码分为两个部分,分别由trycatch包围起来,如果app.go()有错误产生,则Ogre::Exception类型的异常会被抛出,catch部分捕获并处理这个异常。

 

其次,如果没有异常这段代码可能就是这样的:

        If(!app.go()

        {

                  //处理错误

       }

  可以看出如果没有异常机制,我们就不得不使用函数的返回值来定义错误,这样,不但错误信息不准确,而且导致程序的错误处理代码与应用代码混在一起,不易于维护。

 

 

Ogre对异常处理的支持

Ogre::Exception

        Ogre定义了自己的异常类型Ogre::Exception,它记录了错误地详细信息(错误编号、详细描述、错误发生的文件名、行数等)。当有错误发生的时候,Ogre会抛出这个类型的异常,并把这个异常记录的错误信息写入到LogManager的默认日志文件中。

        Ogre::Exception提供了一个成员函数getFullDescription,它的返回值是String类型的,保存了对错误的详细描述。

        Ogre::Exception维护了一个函数名称堆栈,提供了一个入栈函数pushFunction,它接受一个String类型的参数。和一个出栈函数_popFunction,我们需要在每个函数的起始位置调用_pushFunction,并把该函数的额函数名当做参数传入,在结束位置调用_popFunction.

 

 

 

通过查看代码可以看到真个异常定义是通过工厂模式来实现的,首先是定义一个异常类,然后通过继承该类并添加不同的附加信息形成信息携带不同的异常类,最后用一个异常工厂来完成异常的判断。

 

#ifndef __Exception_H_

#define __Exception_H_

 

// Precompiler options

#include "OgrePrerequisites.h"

#include "OgreHeaderPrefix.h"

#include "OgreString.h"

#include <exception>

 

// Backwards compatibility with old assert modedefinitions

#if OGRE_RELEASE_ASSERT == 1

 define OGRE_ASSERT_MODE 1

#endif

 

// Check for OGRE assert mode

//------------------------------------------------------以下是针对于不同判定模式所采用的错误机制------------------------------------------------------------//

 

           

 

// RELEASE_EXCEPTIONS mode

#if OGRE_ASSERT_MODE == 1

  ifdef_DEBUG

     define OgreAssert( a, b ) assert( (a)&& (b) )

 

 else

     if OGRE_COMP != OGRE_COMPILER_BORL

         define OgreAssert( a, b ) if( !(a) ) OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, (b), "no function info")

     else

         define OgreAssert( a, b ) if( !(a) ) OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, (b), __FUNC__)

     endif

 

 endif

 

// EXCEPTIONS mode

#elif OGRE_ASSERT_MODE == 2

 ifOGRE_COMP != OGRE_COMPILER_BORL

     define OgreAssert( a, b ) if( !(a) ) OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, (b), "no function info")

 else

     define OgreAssert( a, b ) if( !(a) ) OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, (b), __FUNC__)

 endif

 

// STANDARD mode

#else

 define OgreAssert( a, b ) assert( (a)&& (b) )

 

#endif

 

namespace Ogre {

   

   

   

   class _OgreExport Exception :public std::exception //-----------------------定义了异常类的全部内容

   {

   protected:

       long line;

       int number;

       String typeName;

       String description;

       String source;

       String file;

       mutable String fullDesc;

   public:

       

       enum ExceptionCodes{   //===================================定义了异常代码的枚举类型

           ERR_CANNOT_WRITE_TO_FILE,

           ERR_INVALID_STATE,

           ERR_INVALIDPARAMS,

           ERR_RENDERINGAPI_ERROR,

           ERR_DUPLICATE_ITEM,

           ERR_ITEM_NOT_FOUND,

           ERR_FILE_NOT_FOUND,

           ERR_INTERNAL_ERROR,

           ERR_RT_ASSERTION_FAILED,

           ERR_NOT_IMPLEMENTED

       };

 

       

       Exception( int number, const String& description,const String&source );

 

       

       Exception( int number, const String& description,const String&source, const char* type, const char*file, long line );

 

       

       Exception(constException& rhs);

 

       /// Needed for compatibility with std::exception

       ~Exception() throw() {}

 

       

       void operator = (const Exception&rhs);

 

       

       virtual const String&getFullDescription(void)const;

 

       

       virtual int getNumber(void) constthrow();

 

       

       virtual const String &getSource()const { return source; }

 

       

       virtual const String &getFile()const { return file; }

 

       

       virtual long getLine() const { returnline; }

 

       

       virtual const String&getDescription(void) const {return description; }

 

       /// Overridestd::exception::what

       const char* what() const throw() {returngetFullDescription().c_str(); }

       

   };

 

 

   

   template<intnum>

   structExceptionCodeType   //里面包含了异常的编码

   {

       enum { number = num };

   };

   //通过继承上面的Exception类来定义不同的异常类型

   // Specialised exceptions allowing eachto be caught specifically

   // backwards-compatible since exceptioncodes still used

 

   class _OgreExportUnimplementedException : publicException

   {

   public:

       UnimplementedException(intinNumber, constString& inDescription, const String& inSource,const char* inFile, long inLine)

           : Exception(inNumber, inDescription, inSource, "UnimplementedException", inFile, inLine){}

   };

   class _OgreExportFileNotFoundException : publicException

   {

   public:

       FileNotFoundException(int inNumber,const String&inDescription, constString& inSource, const char*inFile, long inLine)

           : Exception(inNumber, inDescription, inSource, "FileNotFoundException", inFile, inLine){}

   };

   class _OgreExport IOException :public Exception

   {

   public:

       IOException(int inNumber,const String&inDescription, constString& inSource, const char*inFile, long inLine)

           : Exception(inNumber, inDescription, inSource, "IOException", inFile, inLine) {}

   };

   class _OgreExportInvalidStateException : publicException

   {

   public:

       InvalidStateException(int inNumber,const String&inDescription, constString& inSource, const char*inFile, long inLine)

           : Exception(inNumber, inDescription, inSource, "InvalidStateException", inFile, inLine){}

   };

   class _OgreExportInvalidParametersException : publicException

   {

   public:

       InvalidParametersException(intinNumber, constString& inDescription, const String& inSource,const char* inFile, long inLine)

           : Exception(inNumber, inDescription, inSource, "InvalidParametersException", inFile,inLine) {}

   };

   class _OgreExportItemIdentityException : publicException

   {

   public:

       ItemIdentityException(int inNumber,const String&inDescription, constString& inSource, const char*inFile, long inLine)

           : Exception(inNumber, inDescription, inSource, "ItemIdentityException", inFile, inLine){}

   };

   class _OgreExportInternalErrorException : publicException

   {

   public:

       InternalErrorException(intinNumber, constString& inDescription, const String& inSource,const char* inFile, long inLine)

           : Exception(inNumber, inDescription, inSource, "InternalErrorException", inFile, inLine){}

   };

   class _OgreExportRenderingAPIException : publicException

   {

   public:

       RenderingAPIException(int inNumber,const String&inDescription, constString& inSource, const char*inFile, long inLine)

           : Exception(inNumber, inDescription, inSource, "RenderingAPIException", inFile, inLine){}

   };

   class _OgreExportRuntimeAssertionException : publicException

   {

   public:

       RuntimeAssertionException(intinNumber, constString& inDescription, const String& inSource,const char* inFile, long inLine)

           : Exception(inNumber, inDescription, inSource, "RuntimeAssertionException", inFile, inLine){}

   };

 

 

   

   classExceptionFactory  //异常工厂,通过此类可以调用相关的静态函数create上面定义的所有异常类型,构造是通过异常号来判断的,返回的是异常类的句柄

   {

   private:

       /// Private constructor, noconstruction

       ExceptionFactory() {}

   public:

       static UnimplementedExceptioncreate(

           ExceptionCodeType<Exception::ERR_NOT_IMPLEMENTED>code,

           const String&desc,

           const String& src,const char* file, long line)

       {

           returnUnimplementedException(code.number, desc, src, file,line);

       }

       static FileNotFoundExceptioncreate(

           ExceptionCodeType<Exception::ERR_FILE_NOT_FOUND>code,

           const String&desc,

           const String& src,const char* file, long line)

       {

           returnFileNotFoundException(code.number, desc, src, file,line);

       }

       static IOExceptioncreate(

           ExceptionCodeType<Exception::ERR_CANNOT_WRITE_TO_FILE>code,

           const String&desc,

           const String& src,const char* file, long line)

       {

           return IOException(code.number,desc, src, file, line);

       }

       static InvalidStateExceptioncreate(

           ExceptionCodeType<Exception::ERR_INVALID_STATE>code,

           const String&desc,

           const String& src,const char* file, long line)

       {

           returnInvalidStateException(code.number, desc, src, file,line);

       }

       static InvalidParametersExceptioncreate(

           ExceptionCodeType<Exception::ERR_INVALIDPARAMS>code,

           const String&desc,

           const String& src,const char* file, long line)

       {

           returnInvalidParametersException(code.number, desc, src, file,line);

       }

       static ItemIdentityExceptioncreate(

           ExceptionCodeType<Exception::ERR_ITEM_NOT_FOUND>code,

           const String&desc,

           const String& src,const char* file, long line)

       {

           returnItemIdentityException(code.number, desc, src, file,line);

       }

       static ItemIdentityExceptioncreate(

           ExceptionCodeType<Exception::ERR_DUPLICATE_ITEM>code,

           const String&desc,

           const String& src,const char* file, long line)

       {

           returnItemIdentityException(code.number, desc, src, file,line);

       }

       static InternalErrorExceptioncreate(

           ExceptionCodeType<Exception::ERR_INTERNAL_ERROR>code,

           const String&desc,

           const String& src,const char* file, long line)

       {

           returnInternalErrorException(code.number, desc, src, file,line);

       }

       static RenderingAPIExceptioncreate(

           ExceptionCodeType<Exception::ERR_RENDERINGAPI_ERROR>code,

           const String&desc,

           const String& src,const char* file, long line)

       {

           returnRenderingAPIException(code.number, desc, src, file,line);

       }

       static RuntimeAssertionExceptioncreate(

           ExceptionCodeType<Exception::ERR_RT_ASSERTION_FAILED>code,

           const String&desc,

           const String& src,const char* file, long line)

       {

           returnRuntimeAssertionException(code.number, desc, src, file,line);

       }

 

   };

   

 

   

#ifndef OGRE_EXCEPT

#define OGRE_EXCEPT(num, desc, src) throw Ogre::ExceptionFactory::create(\

   Ogre::ExceptionCodeType<num>(), desc,src, __FILE__, __LINE__ );

#endif

   

   

 

} // NamespaceOgre

 

#include "OgreHeaderSuffix.h"

#endif

Ogre异常处理举例:

//Log.cpp

 materialApplicationapp;

try{

       app.go();

}catch(Exception& e){

#if OGRE_PLATFORM==PLATFORM_WIN32

   //如果是WIN32平台,就弹出一个错误对话框,显示错误地详细信息。

       MessageBoxNULL,e.getFullDescription().c_str(),"An exception hasoccured!",MB_OK|MB_ICONERROR|MB_TASKMODAL);

#else

   //如果不是Win32平台,则直接输出错误的详细信息

   fprintfstderr,"An exceptionhas occured:%s\n,e.getFullDescription().c_str());

       //Log.h

       //定义一个函数Wudi1,在内部无端地抛出一个异常

   void Wudi1()

   {

       OgreGuard("Wudi1"); //将函数名称压入堆栈

       Except888,"wudi","wudi1");//抛出一个异常

       OgreUnguard();           //弹出栈顶元素

   }

   //定义一函数Wudi2,在内部调用Wudi1

   void Wudi2()

   {

       OgreGuard("Wudi2");//将函数名称压入堆栈

       Wudi1();          //调用Wudi1

       OgreUnguard();    //弹出栈顶元素

   }

   classMaterialApplicationpublic ExampleApplication

   {

   public:

       MaterialApplication(){}

   protected:

       //重载createScene函数

       void createScene(void)

       {

           Wudi2();     //调用Wudi2函数

       }

   };