通过引用传递对象(将超出范围)

Pass object (that will go out of scope) by reference

所以我有这个功能:

addDataToList(..., QVariant metadata) { }

本例中的相关 QVariant 构造函数是:QVariant(const QString & val).

现在我有一个函数 foo(),我从那里调用 addDataToList() 函数。 如何将有效值传递给 QVariant 对象?

如果我有这样的东西:

void foo() {
    QString str = "String";
    addDataToList(..., QVariant(str));
}

它不会工作,因为 str 对象将超出范围,导致未定义的行为。

但是如果我在堆上创建字符串,就像这样:

void foo() {
    QString *str = new QString("String");
    addDataToList(..., QVariant(*str));
}

它会工作,但会有一些内存泄漏(因为 QVariant 没有获得传递的指针的所有权)。

如何解决这种情况?

编辑:这是 addDataToList(...):

的实际实现
void TPMSvalidator::addDataToList(const QString &data, bool useMetadata, MessageTypes type, QVariant metadata) {
    QString text;
    QIcon okIcon(QDir::currentPath() + "\Resources\Icons\ok3.png");
    QIcon notOkIcon(QDir::currentPath() + "\Resources\Icons\notok.png");
    QIcon noticeIcon(QDir::currentPath() + "\Resources\Icons\warning2.png");

    if (data != QString()) {
        QListWidgetItem *data_w = new QListWidgetItem;

        if (type == MessageTypes::notification) {
            data_w->setBackgroundColor(QColor(Qt::GlobalColor::gray));
            data_w->setTextColor(QColor(Qt::GlobalColor::black));
            data_w->setIcon(noticeIcon);
            text.append("NOTICE: ");
        }
        else if (type == MessageTypes::telegramOkInfo) {
            data_w->setBackgroundColor(QColor(Qt::GlobalColor::gray));
            data_w->setTextColor(QColor(Qt::GlobalColor::black));
            data_w->setIcon(okIcon);
            text.append("INFO: ");
        }
        else if (type == MessageTypes::telegramNotOkInfo) {
            data_w->setBackgroundColor(QColor(Qt::GlobalColor::gray));
            data_w->setTextColor(QColor(Qt::GlobalColor::red));
            data_w->setIcon(notOkIcon);
            text.append("INFO: ");
        }
        else if (type == MessageTypes::warning) {
            data_w->setBackgroundColor(QColor(Qt::GlobalColor::darkYellow));
            data_w->setTextColor(QColor(Qt::GlobalColor::black));
            text.append("WARNING: ");
        }
        else {
            data_w->setBackgroundColor(QColor(Qt::GlobalColor::darkRed).light(130));
            data_w->setTextColor(QColor(Qt::GlobalColor::white));
            data_w->setIcon(notOkIcon);
            text.append("ERROR: ");
        }

        text.append(data);
        data_w->setText(text);
        data_w->setFont(QFont("Helvetica"));

        if (useMetadata) {
            data_w->setData(Qt::UserRole, metadata);
        }

        ui.listData->addItem(data_w);

        if (ui.autoScrollCheckBox->isChecked()) {
            ui.listData->scrollToBottom();
        }
    }
}

堆栈上带有临时对象的第一个版本将安全地工作,因为临时 QString 是按值复制到 QVariant 中的 - 而不仅仅是引用。

addDataToList(..., QVariant metadata) { }

您正在按值取 QVariant。因此,您将复制传递给函数的值。所以在

addDataToList(..., QVariant(str));

您创建了一个临时文件 QVariant,该临时文件的内容被复制到 addDataToList() 中的 metadata。现在 metadata 是它自己的对象,不依赖于您创建的临时对象。