不要在临时

时间:2018-02-20 01:01:54

标签: c++ qt

我在代码上运行clazy并收到有关此类代码的警告:

QChar value() const
{
    if (hide_content_)
        return '\0';
    else
        return text()[0];
}

其中text()具有此类签名QString text() const;

警告是:

warning: Don't call QString::operator[]() on temporary
      [-Wclazy-detaching-temporary]
            return text()[0];
                   ^

但它是什么意思?是否可能会销毁临时QString对象 在致电operator[]之前?

1 个答案:

答案 0 :(得分:5)

  

在调用operator []之前是否可能销毁临时QString对象?

不,警告不是一个不安全的操作。此处的行为完全定义为临时值aren't destroyed,直到创建它们的完整表达式结束(即直到您的案例中return语句结束)。

摘要:警告是关于与操作相关的性能问题。您可以使用.at(0)代替.operator[](0)进行修复。有关解释,请继续阅读答案。

首先,Qt的容器是implicitly shared;这意味着当您复制容器时,其元素实际上不会被复制,直到对容器执行写入操作(也称为写时复制)。

这意味着只要容器检测到写入操作,就需要分离(执行深层复制),以便这种隐式共享对用户保持透明。

这包括容器向其中的项目发出非const引用的情况(正是非const operator[]正在做的事情),因为它事先无法知道你(容器) user)实际上将使用这些非const引用。

换句话说,我们说当你写QString str = "abc";时我们有一个QChar ch = str[0];QString的非常数operator[]被调用并且,对于容器,这正是用户写入str[0] = 'x';时所了解的内容。这意味着只要在其上调用非const操作,容器就需要分离。当用户真的不想改变容器中的任何东西时,使用const函数是用户的工作。

Clazy在这里试图检测用户在临时内部获取非const引用的情况(因为对于即将被销毁的临时变更没有任何意义)。

有关详情:

  1. Uncovering 32 Qt best practices at compile time with clazy - 请参阅#8
  2. Effective Qt - Marc Mutz - Meeting C++ 2015