C++ 如何使用C++/Qt-内存分配有效吗?
我最近开始为自己调查Qt,并有以下问题: 假设我有一些C++ 如何使用C++/Qt-内存分配有效吗?,c++,qt,memory,shared-ptr,memory-leaks,C++,Qt,Memory,Shared Ptr,Memory Leaks,我最近开始为自己调查Qt,并有以下问题: 假设我有一些QTreeWidget*widget。在某个时刻,我想向它添加一些项目,这是通过以下调用完成的: QList<QTreeWidgetItem*> items; // Prepare the items QTreeWidgetItem* item1 = new QTreeWidgetItem(...); QTreeWidgetItem* item2 = new QTreeWidgetItem(...); items.append(
QTreeWidget*widget
。在某个时刻,我想向它添加一些项目,这是通过以下调用完成的:
QList<QTreeWidgetItem*> items;
// Prepare the items
QTreeWidgetItem* item1 = new QTreeWidgetItem(...);
QTreeWidgetItem* item2 = new QTreeWidgetItem(...);
items.append(item1);
items.append(item2);
widget->addTopLevelItems(items);
但我不知道Qt本身是否会尝试对我的指针进行显式的delete
调用(这将是灾难性的,因为我将它们声明为shared\u ptr
-managed)
你将如何解决这个问题?也许一切都很明显,我错过了一些非常简单的东西?Qt有自己的智能指针,看看。通常情况下,建议尽可能使用Qt的标准所有权层次结构。这一概念如下所述: 对于您的具体示例,这意味着您应该将指向容器(即QTreeWidget)的指针传递给子对象的构造函数。每个QWidget子类构造函数都会为此目的使用一个指向QWidget的指针。当您将子对象指针传递到容器时,容器将接管清理子对象的责任。以下是您需要修改示例的方式:
QTreeWidgetItem* item1 = new QTreeWidgetItem(..., widget);
QTreeWidgetItem* item2 = new QTreeWidgetItem(..., widget);
(我不知道您的示例中的…是什么,但Qt内存管理的重要内容是最后一个参数)
您使用智能指针的示例
shared_ptr<QTreeWidgetItem> ptr(new QTreeWidgetItem(...));
items.append(ptr.get());
shared_ptr ptr(新的QTreeWidgetItem(…);
items.append(ptr.get());
这不是一个好主意,因为您打破了智能指针的黄金法则:永远不要直接使用智能指针管理对象的原始指针。许多Qt类实例可以使用父QObject*构造。此父对象控制构造的子对象的生存时间。查看QTreeWidgetItem是否可以链接到父窗口小部件,这看起来是这样的,阅读Qt文档: 项目通常由一个 是QTreeWidget的父级 (对于顶级项目)或 QTreeWidgetItem(适用于下方的项目) 树的级别)
快速浏览qtreewidget.cpp可以看到:
void QTreeWidget::clear()
{
Q_D(QTreeWidget);
selectionModel()->clear();
d->treeModel()->clear();
}
void QTreeModel::clear()
{
SkipSorting skipSorting(this);
for (int i = 0; i < rootItem->childCount(); ++i) {
QTreeWidgetItem *item = rootItem->children.at(i);
item->par = 0;
item->view = 0;
delete item; // <<----- Aha!
}
rootItem->children.clear();
sortPendingTimer.stop();
reset();
}
void QTreeWidget::clear()
{
Q_D(QTreeWidget);
selectionModel()->clear();
d->treeModel()->clear();
}
void QTreeModel::clear()
{
SkipSorting SkipSorting(这个);
对于(int i=0;ichildCount();++i){
QTreeWidgetItem*item=rootItem->children.at(i);
项目->标准杆=0;
项目->视图=0;
delete item;//addTopLevelItems()确实会导致QTreeWidgetItems拥有QTreeWidgetItems的所有权。因此,您不应该自己删除它们,或者将它们保存在共享的\u ptr中,否则最终会出现双重删除问题。M。因此,如果我像您编写的那样将我的子项“绑定”到父小部件,是否可以确保clear()
例如,调用将处理该内存?是的,您可以。只要您使用Qt的内存管理,Qt就会确保在删除其父对象时删除所有对象(因此Qt严格基于父子内存管理的树进行操作。如果您使用append()或addWidget())或者类似的函数,您不需要在构造函数中明确地设置父函数,尽管这样做不会有什么坏处。
void QTreeWidget::clear()
{
Q_D(QTreeWidget);
selectionModel()->clear();
d->treeModel()->clear();
}
void QTreeModel::clear()
{
SkipSorting skipSorting(this);
for (int i = 0; i < rootItem->childCount(); ++i) {
QTreeWidgetItem *item = rootItem->children.at(i);
item->par = 0;
item->view = 0;
delete item; // <<----- Aha!
}
rootItem->children.clear();
sortPendingTimer.stop();
reset();
}