我对我的代码运行clazy并得到有关此类代码的警告:
QChar value() const
{
if (hide_content_)
return '\0';
else
return text()[0];
}
Run Code Online (Sandbox Code Playgroud)
哪里text()有这样的签名QString text() const;
警告是:
warning: Don't call QString::operator[]() on temporary
[-Wclazy-detaching-temporary]
return text()[0];
^
Run Code Online (Sandbox Code Playgroud)
但是这是什么意思?是否可能QString在调用之前销毁临时对象operator[]?
在调用operator []之前,是否可能会销毁临时QString对象?
不,警告不是一个不安全的操作.这里的行为是完全定义的,因为临时数据在创建它们的完整表达式结束之前不会被销毁(即直到return你的情况下语句的结尾).
摘要:警告是关于与操作相关的性能问题.您可以使用.at(0)而不是使用它来修复它.operator[](0).有关解释,请继续阅读答案.
首先,Qt的容器是隐含共享的 ; 这意味着当您复制容器时,在对容器执行写入操作(也称为copy-on-write)之前,其元素实际上不会被复制.
这意味着只要容器检测到写入操作,就需要分离(执行深层复制),以便这种隐式共享对用户保持透明.
这包括容器向其中的项目发出非const引用的情况(正是非const operator[]正在做的事情),因为它无法事先知道您(容器用户)将如何实际使用这些非const引用.
换句话说,假设我们有一个QString str = "abc";写入的时候QChar ch = str[0];,QString非const operator[]被调用,而对于容器,这正是用户写入时所知道的str[0] = 'x';.这意味着只要在其上调用非const操作,容器就需要分离.当用户不想真正改变容器中的任何东西时,使用const函数是用户的工作.
Clazy在这里试图检测用户在临时内部获取非const引用的情况(因为改变一个即将被销毁的临时变量没有意义).
欲获得更多信息: