gpt4 book ai didi

c++ - unique_ptr 的多个实例

转载 作者:太空宇宙 更新时间:2023-11-04 15:35:21 24 4
gpt4 key购买 nike

在发现我需要 delete任何new我创建的指针,我很快意识到我的项目充满了内存泄漏,我什至不知道。所以提示我使用智能指针。但是,在尝试创建智能指针的多个实例时遇到问题。我创建了一个 SSCE 来更好地解释这一点。

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <memory>
#include "classa.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void on_pushButton_clicked();

private:
Ui::MainWindow *ui;
std::unique_ptr<ClassA> classa; //<----- a smart pointer of a Class type
};

#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "classa.h"
#include <QDebug>

QVector<ClassA*> classes;//<------ QVector that contains instances of ClassA
//So I can retrieve them later based on an index.

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
classa = std::unique_ptr<ClassA>(new ClassA()); //<---- Created here
classes.push_back(classa.get()); //<---- appended to the QVector
}

MainWindow::~MainWindow()
{
delete ui;
}

//When the button is clicked, the program crashes when trying to qDebug
//because the first instance that was loaded in the QVector is no longer
//"valid." It stops being "valid" when I create the second instance of ClassA
void MainWindow::on_pushButton_clicked()
{
classa = std::unique_ptr<ClassA>(new ClassA());
classes.push_back(classa.get());

qDebug() << classes.at(0);
}

希望以上评论足以说明问题。我想到的第一个解决方案是将我在 mainwindow.h 中的声明更改为 std::unique_ptr<ClassA> *classa;但这不会破坏智能指针的目的吗?

真的很迷茫。感谢您的宝贵时间。

最佳答案

我认为你困惑的核心是关于什么 std::unique_ptr<>实际上确实

从您的 MainWindow 构造函数:

classa = std::unique_ptr<ClassA>(new ClassA());

classa现在(巧妙地)指向 ClassA实例#1。 如果该内存引用超出范围,内存将被删除,避免内存泄漏。

classes.push_back(classa.get());

classes[0]现在持有一个指向实例 #1 的(哑)指针。

从您的按钮点击事件处理程序:

classa = std::unique_ptr<ClassA>(new ClassA());

classa现在(巧妙地)指向 ClassA实例#2。

通过为 classa 分配新值,旧的超出了范围。为实例 #1 分配的内存现在解除分配。这就是智能指针的目的

classes[0]仍然持有一个指向内存的(哑)指针先前由实例#0持有。 (你知道这是怎么回事,不是吗?)

classes.push_back(classa.get());

classes[1]现在持有一个指向实例 #2 的(哑)指针。

qDebug() << classes.at(0);

未定义的行为,你死了。


如果您的内存由智能指针管理——正如您应该的那样——它由智能指针管理。不要.get()从它们中取出哑指针并将它们存储在其他地方。


因为你的例子没有告诉我们 classes 是什么vector 应该用于,目前很难给出正确的建议。

  • 您可以使用 vector< ClassA >存储 ClassA 的实例直接。
  • 您可以使用 vector< std::shared_ptr< ClassA > >存储智能指针并在别处使用它们。(*)

或者...

  • 您可以告诉我们您试图解决的实际问题,我们可以告诉您最好的容器是什么。 ;-)

(*):

std::shared_ptr<>std::unique_ptr<>的更强大的 sibling .唯一指针是唯一,它们不能被复制。从好的方面来看,它们与您使用的“普通”指针一样有效delete手动。

std::shared_ptr<>添加一点(微小的)簿记,即存在的拷贝数(因为它可以被复制),并且仅当智能的最后拷贝时才删除内存指针超出范围。

要么依赖存储(和使用)它们包含的指针。

关于c++ - unique_ptr 的多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35622114/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com