我是靠谱客的博主 激动小海豚,最近开发中收集的这篇文章主要介绍MyTinySTL阅读笔记---概述简介六大组件文件分布测试,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 简介
  • 六大组件
  • 文件分布
  • 测试
    • 对do...while(0)的疑惑
    • 使用

简介

STL一直在使用,有时候就想了解了解其中的实现原理,顺便复习复习数据结构和算法。
因为我水平有限,所以先找了一个简化版的MyTinySTL源码来看,配上STL源码剖析这本书,大概是能看懂一些了,这边简单记录一下。
并且还搬运了一些STL源码分析上面的内容,实在是比较懒,想看完整的可以看原本的博客。

六大组件

  1. 分配器:用来管理内存。
  2. 迭代器:将容器和算法粘合在一起,用来遍历STL容器中的部分或全部元素。
  3. 容器:封装了大量常用的数据结构。
  4. 算法:定义了一些常用算法。
  5. 仿函数:具有函数特质的对象。
  6. 适配器:主要用来修改接口。

在这里插入图片描述

文件分布

组件文件
分配器construct.h、allocator.h
迭代器iterator.h、type_traits.h
容器astring.h、basic_string.h、vector.h、list.h、deque.h、stack.h、queue.h、rb_tree.h、set.h、map.h、hashtable.h、unordered_set.h、unordered_map.h
算法uninitialized.h、algorithm.h、algobase.h、algo.h、set_algo.h、heap_algo.h、numeric.h
仿函数functional.h
配接器分布在很多角落

测试

MyTinySTL自己编写了函数用来测试都在test.h中,注释很全。

首先定义了输出的颜色,green代表成功 red代表失败。

#define green redbud::io::state::manual << redbud::io::hfg::green
#define red   redbud::io::state::manual << redbud::io::hfg::red

然后有两个类分别是单个测试和运行多个测试。

// 封装单个测试案例
class TestCase
{
public:
	// 构造函数,接受一个字符串代表案例名称
	TestCase(const char* case_name) : testcase_name(case_name) {}

	// 一个纯虚函数,用于测试案例
	virtual void Run() = 0;

public:
	const char* testcase_name;  // 测试案例的名称
	int         nTestResult;    // 测试案例的执行结果 
	double      nFailed;        // 测试失败的案例数
	double      nPassed;        // 测试通过的案例数
};
// 单元测试,把所有测试案例加入到 vector 中,依次执行测试案例
class UnitTest
{
public:
	// 获取一个案例
	static UnitTest* GetInstance();

	// 将案例依次加入 vector
	TestCase* RegisterTestCase(TestCase* testcase);

	void Run();

public:
	TestCase* CurrentTestCase;          // 当前执行的测试案例
	double    nPassed;                  // 通过案例数
	double    nFailed;                  // 失败案例数

protected:
	std::vector<TestCase*> testcases_;  // 保存案例集合
};

实现都很简单,后面还有一系列的宏用来进行断言操作。

对do…while(0)的疑惑

刚开始看的时候我还是很好奇为什么宏定义中要用do...while(0),如:

#define EXPECT_TRUE(Condition) do {                             
  if (Condition) {                                              
    UnitTest::GetInstance()->CurrentTestCase->nPassed++;        
    std::cout << green << " EXPECT_TRUE succeeded!n";          
  }                                                             
  else {                                                        
    UnitTest::GetInstance()->CurrentTestCase->nTestResult = 0;  
    UnitTest::GetInstance()->CurrentTestCase->nFailed++;        
    std::cout << red << " EXPECT_TRUE failed!n";               
}} while(0)

既然循环里面只执行了一次,我要这个看似多余的do...while(0)有什么意义呢?

我们举个例子
有一个宏:

#define _DELETE(p) do{ delete p; p = NULL} while(0)

去掉do…while(0):

#define _DELETE(p) delete p; p = NULL;

调用

if(NULL != p) _DELETE(p)
else   ...do sth...

可能有人已经发现了去掉do…while(0)我们的代码可能会变成:

if(NULL != p) delete p; p = NULL;
else   ...do sth...

if分支后有两个语句,else分支没有对应的if,编译失败。
假设没有else, _DELETE中的第二个语句无论if测试是否通过,会永远执行。

有人说我写的if绝对加{},但是我们不能保证其他人对吧。

还有人可能会想我不能用{}吗一定要用do...while(0)吗?
的确,这样的话上面的问题是不存在了,但是我想对于C++程序员来讲,在每个语句后面加分号是一种约定俗成的习惯,这样的话,以下代码:

if(NULL != p) _DELETE(p);
else   ...do sth...

else就没法编译了。

使用

TEST(first)
{
	EXPECT_TRUE(true);
}

int main()
{
	RUN_ALL_TESTS();

	return 0;
}

运行结果:
在这里插入图片描述

最后

以上就是激动小海豚为你收集整理的MyTinySTL阅读笔记---概述简介六大组件文件分布测试的全部内容,希望文章能够帮你解决MyTinySTL阅读笔记---概述简介六大组件文件分布测试所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部