C++ 项目成长 —— 自定义系统中使用的Assert工具,类似Q_ASSERT的简化版

27 篇文章 0 订阅
16 篇文章 0 订阅

自定义系统中使用的Assert工具,类似Q_ASSERT的简化版

概要

     书接上回,项目开始定义了一些系统的平台参数,具体可参见下面的文章:C++ 项目成长 —— 定义跨平台的参数宏的文件记录

     同时,在上次我们尝试去定义了一些编译选项自定义的宏,来控制不同的编译选项的时候,能够做一些区分,具体可以参考下面的文章:C++ 项目成长 —— 自定义编译参数宏,区分编译选项

     上回说到一下关于自定义一些自己项目中所用到的数据类型,那么可以参考上次的文章:
C++ 项目成长 ——自定义数据类型,定义各种类型别名, typedef的部分用法实例

     这次呢,我们定义了一些类型之后,有时候会在项目中,需要去动态调试一些情况,判断是否存在空指针,最终得到的某些结果是否是我们期望的判断条件等,那么就需要用一个运行时的Assert来告诉我们,可能项目出错,中断在了什么地方,哪里是有问题的,方便我们在以后写代码的过程中,能够更快的去定位到问题,这种情况尤其更适用于寻找内存出错的问题。那么,我就把自己写的一个简陋的Assert给分享出来吧。

TZOpenTools

tzsofts_assert.h

///
// Copyright (c)2021, Tom Zhao personal. ("TZOpenTools")
// This software is a personal tools project by Tom Zhao.
// Description:
///

#ifndef _TZSOFTS_ASSERT_H_H
#define _TZSOFTS_ASSERT_H_H

#include "zsofts_types.h"
#include "platform_export.h"

#ifdef TZ_WINDOWS
#include <crtdbg.h>
#else
#include <stdio.h>
#include <wchar.h>
#endif // TZ_WINDOWS

#include <assert.h>

#pragma pack(push, 8)

TZ_NAMESPACE_BEGIN(TzSoft)

typedef void(*TzAssertFunc) (const TZTCHAR* expression, const TZTCHAR* fileName, int lineNumber);

class TZ_PLATFORM_STATIC_EXPORT Asserter 
{
public:
	Asserter(const TZTCHAR* expression, const TZTCHAR* fileName, int lineNumber) 
	{
		// (*sm_pfnAssert)(expression, fileName, lineNumber);
		defaultAssert(expression, fileName, lineNumber);
	}

	~Asserter() 
	{

	}

	static TzAssertFunc setAssertFunction(TzAssertFunc pfnAssert) 
	{
		TzAssertFunc pfnOldFunc = sm_pfnAssert;
		sm_pfnAssert = pfnAssert;
		return pfnOldFunc;
	}

private:
	static void defaultAssert(const TZTCHAR* expression, const TZTCHAR* fileName, int lineNumber) 
	{
#if TZ_BUILD_MODE == TZ_BUILD_DEBUG && TZ_COMPILER == TZ_COMPILER_MSVC && TZ_PLATFORM != TZ_PLATFORM_WINCE
#		if TZ_COMPILER_VER >= TZ_COMPILER_MSVC_8_0
		if (1 == _CrtDbgReportW(_CRT_ASSERT, fileName, lineNumber, NULL, expression))
			_CrtDbgBreak();
#		elif TZ_COMPILER_VER >= TZ_COMPILER_MSVC_7_0
			_assert(expression, fileName, lineNumber);
#		else
		_assert((void *)expression, (void *)fileName, lineNumber);
#		endif
#endif // TZ_BUILD_MODE == TZ_BUILD_DEBUG && TZ_COMPILER == TZ_COMPILER_MSVC && TZ_PLATFORM != TZ_PLATFORM_WINCE

	}

	TZ_PLATFORM_EXPORT_STATIC static TzAssertFunc	sm_pfnAssert;
};

TZ_NAMESPACE_END(TzSoft)

#endif // !_TZSOFT_ASSERT_H_H

tzsofts_assert.cpp

///
// Copyright (c)2020, Tom Zhao personal. ("TZOpenTools")
// This software is a personal tools project by Tom Zhao.
// Description:
///

#include "pch.h"
#include "tzsofts_assert.h"

TZ_NAMESPACE_BEGIN(TzSoft)

#if defined(TZ_WINDOWS)

#if defined(TZ_USE_DEBUGOUTPUT_FOR_ASSERTION_FAIL)
void debugOutputAssert(const TZTCHAR* expression, const TZTCHAR* fileName, int lineNumber) 
{
	static const TZCHAR* _s_debug_assertion_fmt = TZ_T("\nASSERT FAIL!!!!\nExpression:\"%s\"\nOccur at:\"%s(line %d)\"\n");
	const size_t _debug_assertion_fmt_strlen = tz_strlen(_s_debug_assertion_fmt) +
		(NULL == expression ? 1 : tz_strlen(expression)) +
		(NULL == fileName ? 1 : tz_strlen(fileName)) + 20;
	TZCHAR * _assertInfoForStr = new TZCHAR[_debug_assertion_fmt_strlen];

	if (tz_stprintf(_assertInfoForStr, _s_debug_assertion_fmt, expression, fileName, lineNumber) > 0) 
	{
		::OutputDebugString(_assertInfoForStr);
	}
	delete[] _assertInfoForStr;
}

TZ_PLATFORM_STATIC_EXPORT TzAssertFunc Asserter::sm_pfnAssert = debugOutputAssert;
#else

TZ_PLATFORM_STATIC_EXPORT TzAssertFunc Asserter::sm_pfnAssert = Asserter::defaultAssert;

#endif

#else 

// TODO: Put assert method for platform that other than windows.

static void otherAssert(const TZCHAR* expression, const TZCHAR* fileName, int lineNumber) 
{
	wprintf(TZ_T("\nTzAsserter failed -- %ls:%d "), fileName, lineNumber);
}

TZ_PLATFORM_STATIC_EXPORT TzAssertFunc Asserter::sm_pfnAssert = otherAssert;

#endif

TZ_NAMESPACE_END(TzSoft)

个人格言

    用心去感受你自己需要坚持的生活,未来慢慢会给你答案的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值