我已经看过this线程,但是情况完全不同,我无法将该解决方案应用于我的问题。
我有以下构造函数:
Fan::Fan(Id id, std::string name, Age age);
[Id
和Age
是typedef
的无符号int和无符号short。这是给我的,所以我知道我必须使用它们,因为赋值的测试人员很可能会尝试使用大于int的数字(在unsigned int / short范围内)。
显然,风扇的id
和age
不能为负数。在示例代码(要针对其进行编译)中,将创建一个带有id
和age
数字的风扇。我不能在那里使用字符串并检查减号。
我以为在单元测试中输入否定的age
/ id
时不会编译。但是,事实证明它确实进行了编译,并且给出了随机值(很可能是由于溢出原因)。
因此,可以用age
和id
的负值调用构造函数,但是在构造函数中,它们的值被“破坏”并且出现随机数,这会导致意外的行为。
例如,此:
Fan* fan = new Fan(-1, "Name", 9);
编译,并且在运行时,风扇的id
获得一些无关的值。因此,我必须能够在构造函数中检测到负数。我如何“ block”构造函数中的负数?
感谢您的时间!希望我的问题清楚。
我创建了一个小函数模板,该模板检查输入是否在输出数据类型的范围内,否则抛出异常。它要求输入和输出数据类型是整数,并且输入数据类型的大小大于输出数据类型。
template<typename DestType, typename SrcType>
DestType range_check_and_convert(SrcType const& src)
{
static_assert(sizeof(SrcType) > sizeof(DestType),
"SrcType must be larger than DestType");
static_assert(std::is_integral<SrcType>::value &&
std::is_integral<DestType>::value, "integral types only");
if(src > static_cast<SrcType>(std::numeric_limits<DestType>::max())) {
throw std::out_of_range("input too big");
} else if(src < static_cast<SrcType>(std::numeric_limits<DestType>::min())) {
throw std::out_of_range("input too small");
}
return static_cast<DestType>(src);
}
通过声明构造函数仅采用无符号值,您基本上已经“阻止”负数可以作为参数传递。
您仍可以写为将-1
传递给该函数,但是该函数随后看到的是该负数see this question的无符号解释。
例如,在32位Windows应用程序中,传递-1
将导致Id
为0xffffffff
或4294967295
。现在,您必须确定这是否是您应用程序的有效输入,但可能是这样,因为它仍然是一个正数。另一方面,年龄-1
可能是无效的输入,因为它不太可能是4294967295岁。如您所见,您无法检查-1
的未签名值。您必须检查age
是否比例如200大,因为-1作为无符号参数给出时实际上是一个大数字。