C++ 如何在单元测试中引入std::string的边界检查?

C++ 如何在单元测试中引入std::string的边界检查?,c++,string,unit-testing,C++,String,Unit Testing,我有一个模块,它使用std::string作为接口的一部分。我想在这个模块上运行一个单元测试,在std::string的索引访问上使用边界检查。也就是说,如果字符串s只有5个字符,我想在访问s[5](或s[-1])时抛出某种异常 下面是我的代码的基础。该模块全部在单个头文件中实现 模块h 我认为一种方法是根据模板实现module.h,其中实现取决于允许索引的某种类型。但是,module.h中的实现没有理由在现实世界中使用除std::string之外的任何东西;这样的特性只能用于单元测试。我不想在

我有一个模块,它使用
std::string
作为接口的一部分。我想在这个模块上运行一个单元测试,在
std::string
的索引访问上使用边界检查。也就是说,如果字符串
s
只有5个字符,我想在访问
s[5]
(或
s[-1]
)时抛出某种异常

下面是我的代码的基础。该模块全部在单个头文件中实现

模块h 我认为一种方法是根据模板实现
module.h
,其中实现取决于允许索引的某种类型。但是,
module.h
中的实现没有理由在现实世界中使用除
std::string
之外的任何东西;这样的特性只能用于单元测试。我不想在这里使用模板

我可以使用预处理器技巧,只要这些技巧仅限于
test.cpp
模块。例如,在正常情况下,我不希望在包含
module.h
之前必须定义ModuleString std::string


我在这里的选项是什么?

您可以使用
操作符[]
,它已经执行边界检查并将
std::抛出\u范围之外。可行吗?

您可以使用,而不是
操作符[]
,它已经执行边界检查并将
std::抛出\u范围之外。可行吗?

您可以使用
std::string::at
,而不是
运算符[]
,它已经执行边界检查并将
std::抛出\u范围之外。可行吗?这是个好主意。我不知道为什么我不知道!您可以使用
std::string::at
,而不是
运算符[]
,它已经执行边界检查并将
std::抛出\u范围之外。可行吗?这是个好主意。我不知道为什么我不知道!这确实解决了我的问题。然而,我想知道是否还有一种更通用的技术可以为单元测试添加这样的附加功能。这种技术很难(如果不是不可能的话)引入到内置类型中。此外,编译器静态分析也帮不上忙,因为
std::string
使用堆内存(想想gcc中的
-fbounds check
)。一个选项是扩展有问题的类型,覆盖需要边界检查的方法。但是这需要你用扩展类型替换
std::string
的用法,这有点违背目的。是的,我想用
std::boundscheckstring
扩展
std::boundscheckstring
,使用所有合适的构造函数和边界检查实现,然后,
#在适当的时候定义字符串边界检查字符串
,但没有完全解决细节问题。@Greg:考虑一下,我建议创建一个像代理一样的全新类型,有一个
std::string
成员。包装字符串,并在执行边界检查后转发调用。无论如何,找出正确的方法并不是最容易的任务。没错,这将确保为所有可能需要的调用添加边界检查(而不依赖任何继承的实现)。它仍然需要同样的预处理器舞蹈。这确实解决了我的问题。然而,我想知道是否还有一种更通用的技术可以为单元测试添加这样的附加功能。这种技术很难(如果不是不可能的话)引入到内置类型中。此外,编译器静态分析也帮不上忙,因为
std::string
使用堆内存(想想gcc中的
-fbounds check
)。一个选项是扩展有问题的类型,覆盖需要边界检查的方法。但是这需要你用扩展类型替换
std::string
的用法,这有点违背目的。是的,我想用
std::boundscheckstring
扩展
std::boundscheckstring
,使用所有合适的构造函数和边界检查实现,然后,
#在适当的时候定义字符串边界检查字符串
,但没有完全解决细节问题。@Greg:考虑一下,我建议创建一个像代理一样的全新类型,有一个
std::string
成员。包装字符串,并在执行边界检查后转发调用。无论如何,找出正确的方法并不是最容易的任务。没错,这将确保为所有可能需要的调用添加边界检查(而不依赖任何继承的实现)。它仍然需要相同的预处理器舞蹈。
#include <string>

int decode(const std::string &data) { ... }
#include "module.h"

#include "gtest/gtest.h" // using Google Test

TEST(Module, Decode) {
    ASSERT_EQ(decode("...") == 5); // or whatever
}