C++编程调试秘笈----读书笔记(2)

二、运行时的错误

一个可以进行安全检查的宏

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那么,即是要打开安全检查,当检查多的时候,速度会有所下降。

 

你可能感兴趣的:(C++编程调试秘笈----读书笔记(2))