如何正确施放? (或者我应该这样做吗?)

时间:2012-04-05 08:54:18

标签: c++ visual-c++ casting integer

如果我有

等代码
class CString { int GetLength(); };

bool smaller(CString s1, std::string s2) {
    return s2.size() > s1.GetLength();
}

对我来说最好的事情是什么?

  • s1.GetLength()更改为(size_t)c.GetLength()
    这将有助于摆脱关于“签名 - 无符号不匹配”的编译器警告,并传达我的演员意图,并且是迄今为止最简单的路线。但它可能不赞成。 :(

  • s1.GetLength()更改为static_cast<size_t>(c.GetLength())
    通过“正确”的演员阵容,这将有助于摆脱警告。

  • s1.GetLength()更改为static_cast<std::string::size_type>(c.GetLength())
    它非常冗长......这种抽象是否有实际的好处,或者我应该打破它?

  • 保持原样?
    这将有助于编译器使用 /RTCc开关(我的主要关注点)进行溢出检查,但会以警告为代价。

  • 做点其他事情?
    我应该自己制作铸造功能吗?使用宏?我应该在运行时和编译时检查吗?还有其他想法吗?

编辑:

似乎这个例子的字面意思太过分了......

我显然不打算只是谈论CString::GetLength()。这种特殊方法当然不是我的一大担心。 :)我担心的是更多一般的情况,当我得到一个永远不会假设为负的整数,但可能 em>理论上是由于错误。

哎呀,我可能正在编写这样做的方法,以便覆盖另一段代码 - 所以我无法更改签名。而且我的代码肯定会有错误,即使我没想到它。

在这种情况下,我该怎么办?

4 个答案:

答案 0 :(得分:6)

您可以更改GetLength()吗?从根本上说,问题是长度永远不会消极,而无符号类型反映的是最好的。长度不应使用int来衡量。

但除此之外,所有三种解决方案都是相同的。 std::string::size_type总是std::size_t,而我会使用static_cast,在这种情况下,C风格的强制转换会执行相同的强制转换。因为你知道返回的长度永远不会消极(顺便说一句,确保这一点;你永远不知道人们会做些什么奇怪的事情),你完全安全,只需输入类型:

return s2.size() > static_cast<std::size_t>(s1.GetLength());

如果CString::GetLength 可能由于某种原因,那么由您来决定如何将该转化从负转为正。截短?幅度(绝对值)?无论你需要什么。


如果您担心错误,请进行明确检查并抛出异常(取决于您的域名,这可能代价太高),或使用assert。但是,一般来说,您应该信任该文档。

答案 1 :(得分:4)

将演员阵容放在自己的函数中,并带有注释:

std::string::size_type size(const CString& mfcString)
{
    // CString::GetLength is always non-negative
    // http://msdn.microsoft.com/en-us/library/aa300471(v=vs.60).aspx

    return static_cast<std::string::size_type>(mfcString.GetLength());
}

然后您的代码将是:

bool smaller(const CString& s1, const std::string& s2)
{
    return size(s1) < s2.size();
}

答案 2 :(得分:2)

我认为正确的解决方案是更改CString::getLength()的签名以返回无符号类型。鉴于您按价值获取参数,您可能需要考虑为CString提供std::string的转换构造函数(或者您应该更改函数的签名以使其参数{{1} }})。

就我个人而言,我认为该操作是转换而不是转换,并将其写为:

const&

答案 3 :(得分:0)

更改方法CString :: getLength()并返回无符号类型。

试试这个

return std :: string :: size_type(s1.getLength())     &LT; s2.size();