C ++如何阻止将负数作为参数传递给期望无符号的地方

问题描述 投票:2回答:2

我已经看过this线程,但是情况完全不同,我无法将该解决方案应用于我的问题。

我有以下构造函数:

Fan::Fan(Id id, std::string name, Age age);

[IdAgetypedef的无符号int和无符号short。这是给我的,所以我知道我必须使用它们,因为赋值的测试人员很可能会尝试使用大于int的数字(在unsigned int / short范围内)。

显然,风扇的idage不能为负数。在示例代码(要针对其进行编译)中,将创建一个带有idage数字的风扇。我不能在那里使用字符串并检查减号。

我以为在单元测试中输入否定的age / id时不会编译。但是,事实证明它确实进行了编译,并且给出了随机值(很可能是由于溢出原因)。

因此,可以用ageid的负值调用构造函数,但是在构造函数中,它们的值被“破坏”并且出现随机数,这会导致意外的行为。

例如,此:

Fan* fan = new Fan(-1, "Name", 9);

编译,并且在运行时,风扇的id获得一些无关的值。因此,我必须能够在构造函数中检测到负数。我如何“ block”构造函数中的负数?

感谢您的时间!希望我的问题清楚。

c++ constructor unsigned
2个回答
3
投票

我创建了一个小函数模板,该模板检查输入是否在输出数据类型的范围内,否则抛出异常。它要求输入和输出数据类型是整数,并且输入数据类型的大小大于输出数据类型。

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);
}

Live demo


2
投票

通过声明构造函数仅采用无符号值,您基本上已经“阻止”负数可以作为参数传递。

您仍可以写为将-1传递给该函数,但是该函数随后看到的是该负数see this question的无符号解释。

例如,在32位Windows应用程序中,传递-1将导致Id0xffffffff4294967295。现在,您必须确定这是否是您应用程序的有效输入,但可能是这样,因为它仍然是一个正数。另一方面,年龄-1可能是无效的输入,因为它不太可能是4294967295岁。如您所见,您无法检查-1的未签名值。您必须检查age是否比例如200大,因为-1作为无符号参数给出时实际上是一个大数字。

© www.soinside.com 2019 - 2024. All rights reserved.