【发布时间】:2015-12-28 04:49:58
【问题描述】:
所以我有这个功能:
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();
}
}
}
【问题讨论】:
-
如果你这样做,你需要自己处理内存清理。您可以免费使用。
-
QT 示例表明 QVariant 实际上复制了传递的值。你确定不是吗? (即
QVariant x, y(QString()), z(QString(""));在示例中)。在这种情况下它不应该使用 const-ref,但是 QT 并没有那么快地更新到最新的 C++。 -
const &参数一般为 1. 承诺不更改值 2. 避免为函数调用制作副本。它不一定表示将保留引用。 -
QVariant仅存储副本。 (否则它几乎没用。) -
您对第一个场景的解释是错误的......按值传递将临时复制到函数调用堆栈中,即 addDataToList() 将拥有它自己的副本。所以,它不会超出范围跨度>
标签: c++ memory-leaks reference pass-by-reference undefined-behavior