【发布时间】:2016-08-08 10:03:02
【问题描述】:
我正在使用 Cppcheck 1.75 检查我的一个项目,并针对此代码(为清晰起见已简化):
class TJob
{
public:
TJob(std::auto_ptr<ITask> task);
// ...
private:
std::auto_ptr<ITask> m_task;
};
TJob::TJob(
std::auto_ptr<ITask> task // <-- HERE the performance warning
): m_task(task)
{
trace("TJob ctr");
}
我收到了这个新的性能警告:
Id:passedByValue
总结:函数参数'task'应该通过引用传递。
消息:参数“任务”是按值传递的。它可以作为 (const) 引用传递,这通常更快,并且在 C++ 中被推荐。
这显然是误报。在我看来这是一个错误,因为遵循这个建议会导致一个严重的错误[1],但也许有一个我错过设置的开关,或者我可以提供一些模板来声明 所有权由auto_ptr传递?
我在网上搜索了这个,到目前为止我唯一发现的是 Cppcheck 包含了一些对 Check for invalid usage of STL 的检查,例如
- using auto pointer (auto_ptr)
我知道,auto_ptr 不是最佳选择,但与unique_ptr 不一样吗?会不会是两个检查在这里干扰?
除了使用inline supression 之外,是否可以取消针对这些情况的警告?
编辑:添加了脚注。
[1]没有严重的错误,只是对使用std::auto_ptr的一个误解。我以某种方式将编译时与运行时语义混为一谈:所有权不是通过某种编译时魔法传递的,而是在运行时通过调用“复制”构造函数来传递的。
【问题讨论】:
-
你的意思是什么建议导致一个严重的错误?所有权仍然会传递给
m_task,不是吗? -
真的吗?那我真的要深入研究一下了……
-
如果
task是按值传递的,那么对于std::auto_ptr<ITask> my_task(sth); TJob tjob(my_task);,所有权将从my_task传递给参数task,然后传递给成员m_task;如果task通过引用传递,所有权将直接传递给m_task。不是吗? -
@songyuanyao 是的,确实,我刚刚围绕它构建了一个 littla 项目,使这个(部分)可见。我想,我在某处读到
auto_ptr(及其更好的继任者)应该按值传递。我盲目地遵循这一点多么令人尴尬;)(我现在必须在我的小测试中实现复制 ctr 跟踪,才能看到全部真相......) -
implement copy ctr tracing-- 我的错,这是不可能的,因为这需要进入 auto_ptr 的实现;)所以这必须在调试器中进行跟踪。