[英]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.