繁体   English   中英

将auto_ptr与C ++中的引用结合

[英]Combining auto_ptr with references in C++

前一段时间,我决定严格遵循该规则来检查每个指针,然后在范围内首次对其进行引用之前,还适当地更改了指向引用的指针:在某些情况下在代码库中是静态的,在某些情况下是动态的(在声明了指针当然不是null)。 最终导致这样的代码:

std::string LoadText0(const std::string& fileName)
{
    TStrings& lines = *new TStringList;
    lines.LoadFromFile(fileName.c_str());
    std::string result = lines.Text.c_str();
    delete &lines;
    return result;
}

...我不太喜欢,但是与上述规则一致,因为我根本不关心失败的消息:我保证它会根据编译器设置抛出异常。

但是:此代码远非异常安全的。 由于静态分析工具Cppcheck在当前版本1.65中存在问题,说明我尝试删除会导致未定义行为的自动变量,因此我发现缺少值得重写代码的异常安全性,现在我使用的是std::auto_ptr

但是现在,我不喜欢所有的->运算符:它们给人一种错误的感觉,即可以选择分配指针。 当范围变大时,此外观尤其成问题,并且将所有点重写为箭头也需要大量工作。

std::string LoadText1(const std::string& fileName)
{
    std::auto_ptr<TStrings> lines(new TStringList);
    lines->LoadFromFile(fileName.c_str());
    std::string result = lines->Text.c_str();
    return result;
}

因此,我试图找出一种结合了两个方面的优点的解决方案,这就是我所发现的(带有指向同一对象的两个“访问点”的缺点)

std::string LoadText2(const std::string& fileName)
{
    std::auto_ptr<TStrings> plines(new TStringList);
    TStrings& lines = *plines;
    lines.LoadFromFile(fileName.c_str());
    std::string result = lines.Text.c_str();
    return result;
}

这是您眼中的滥杀滥伤吗? 您认为它是惯用的吗?

好吧,这可能只是观点,但我将尝试证明观点的合理性。

我认为在第二个示例中使用->更惯用。 熟练的c ++读者可以立即清楚自己在做什么。

通过将指针变成摘要3中的引用,您正在插入(恕我直言)一条无用的代码行,其唯一好处是可以缓解因使用->运算符而烦恼的任何人。

如果未分配指针,则在尝试将其转换为引用时,将遇到与使用该指针时相同的错误。 因此它什么也没做。 因此,我认为代码既不会完成任何事情,也不会澄清代码-这是噪音,不是信号,在代码审查中,我建议将其删除。

考虑到您必须在堆上分配并且只有auto_ptr可用的限制,我发现您的第二个解决方案是正确的。 为了向代码的读者保证假定已分配了指针,我建议遵循“ C ++编码标准”(Sutter和Alexandrescu->和优秀阅读)中的准则68,该准则指出“自由声明以记录内部假设和不变。“

因此,在初始化(自动)指针之后,立即添加以下行:

断言(线);

对于任何阅读您的代码的人来说,它可以作为文档,您可以肯定地确定没有未初始化的指针将到达代码的那一点,并且它充当对您的假设有效的调试(而非发布)时间测试。 双赢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM