通过引用传递对象(将超出范围)
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
是它自己的对象,不依赖于您创建的临时对象。
所以我有这个功能:
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
是它自己的对象,不依赖于您创建的临时对象。