二、運行時的錯誤 一個可以進行安全檢查的宏 scpp_assert.h: [cpp] #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: [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 } 測試程序: [cpp] <span style="font-size:18px;">// 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; }</span> 這個宏可以合成一條有意義的錯誤,包括與錯誤有關的更多信息: SCPP_ASSERT(0 < stockPrice && stockPrice <= 1.e6, "Stock price " << stockPrice << " is out of range"); 而且在這個宏中,可以使用任何類的對象,只要他定義了<<操作符。比如: [cpp] #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那麼,即是要打開安全檢查,當檢查多的時候,速度會有所下降。