二、运行时的错误
一个可以进行安全检查的宏
scpp_assert.h:
#ifndef __SCCP_ASSERT_H__ #define __SCCP_ASSERT_H__ #include "sstream" #ifdef SCPP_THROW_EXCEPTION_ON_BUG #include "exception" namespace scpp { class ScppAssertFailedException : public std::exception { public: ScppAssertFailedException(const char *file_name, unsigned line_number, const char* message); ~ScppAssertFailedException() throw(){}; public: virtual const char * what() const throw() { return what_.c_str(); } private: std::string what_; }; }// namespace scpp #endif void SCPP_AssertErrorHandler(const char *file_name, unsigned line_number, const char *message); #define SCPP_ASSERT(condition, msg) \ if (!(condition)) \ { \ std::ostringstream s; \ s << msg; \ SCPP_AssertErrorHandler( \ __FILE__, __LINE__, s.str().c_str()); \ } #ifndef _DEBUG #define SCPP_TEST_ASSERT_ON #endif // !_DEBUG #ifdef SCPP_TEST_ASSERT_ON #define SCPP_TEST_ASSERT_ON(condition, msg) SCPP_ASSERT(condition, msg) #else #define SCPP_TEST_ASSERT_ON(condition, msg) // do nothing #endif // !SCPP_TEST_ASSERT_ON #endif // !_SCCP_ASSERT_H_
scpp_assert.cpp:
#include "stdafx.h" #include "scpp_assert.h" #include "iostream" #include "stdlib.h" #ifdef SCPP_THROW_EXCEPTION_ON_BUG namespace scpp { ScppAssertFailedException::ScppAssertFailedException(const char *file_name, unsigned line_number, const char* message) { std::ostringstream ss; ss << "SCPP assertion failed with message '" << message << "' in file " << file_name << " #" << line_number; what_ = ss.str(); } } #endif // SCPP_THROW_EXCEPTION_ON_BUG void SCPP_AssertErrorHandler(const char *file_name, unsigned line_number, const char *message) { #ifdef SCPP_THROW_EXCEPTION_ON_BUG throw scpp::ScppAssertFailedException(file_name, line_number, message); #else std::cerr << message << " in file " << file_name << " #" << line_number << std::endl << std::flush; exit(1); #endif // SCPP_THROW_EXCEPTION_ON_BUG }
测试程序:
// debug.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "scpp_assert.h"
#include "iostream"
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "hello, SCPP_ASSERT" << std::endl;
double stockPrice = 100.0;
SCPP_ASSERT(0 < stockPrice && stockPrice <= 1.e6,
"Stock price " << stockPrice << " is out of range");
stockPrice = -1.0;
SCPP_ASSERT(0 < stockPrice && stockPrice <= 1.e6,
"Stock price " << stockPrice << " is out of range");
return 0;
}
这个宏可以合成一条有意义的错误,包括与错误有关的更多信息:
SCPP_ASSERT(0 < stockPrice && stockPrice <= 1.e6,
"Stock price " << stockPrice << " is out of range");
而且在这个宏中,可以使用任何类的对象,只要他定义了<<操作符。比如:
#include "stdafx.h" #include "scpp_assert.h" #include "iostream" class MyClass { public: bool IsValid(bool flag) { return flag == true ? true : false; } friend std::ostream& operator <<(std::ostream & os, const MyClass &obj); }; inline std::ostream& operator <<(std::ostream & os, const MyClass &obj) { return os; } int _tmain(int argc, _TCHAR* argv[]) { std::cout << "hello, SCPP_ASSERT" << std::endl; MyClass obj; SCPP_ASSERT(obj.IsValid(false), "this object " << obj << " is invalid."); return 0; }
如果一开始定义了SCPP_THROW_EXCEPTION_ON_BUG那么,即是要打开安全检查,当检查多的时候,速度会有所下降。