前言
在 C++ 中,动态分配内存时通常使用 new 关键字,但使用 new 分配的内存不会自动回收,程序员需要手动管理内存。这意味着每次使用 new 分配的内存,都必须使用 delete 来释放,否则会导致 内存泄漏。下面我将详细介绍 C++ 中 new 和内存回收相关的内容。
错误示例
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 通过将 parent 设置为 this,Qt 将自动管理 sender 和 receiver 的生命周期
SendSignal *sender = new SendSignal;
ReceiveSignal *receiver = new ReceiveSignal;
QPushButton *btn = new QPushButton;
btn->setText("close");
btn->setFixedSize(100, 50);
btn->setParent(this);
// 连接信号和槽
connect(btn, &QPushButton::clicked, sender, &SendSignal::exit);
connect(btn, &QPushButton::clicked, receiver, &ReceiveSignal::handleExit);
connect(sender, &SendSignal::exit, receiver, &ReceiveSignal::handleExit2);
qDebug() << "Signals and slots are connected";
delete sender;
delete receiver;
}
MainWindow::~MainWindow()
{
// 不需要手动 delete sender 和 receiver,Qt 会自动管理这些对象
delete ui;
}
上面的代码,按照C++的知识是完全没有问题的。但是因为在代码中手动调用了 delete sender 和 delete receiver,这会导致 sender 和 receiver 对象在按钮点击后被提前销毁,导致信号和槽无法正常工作。当我们点击按钮时,无法响应信号
解决方案
使用父子关系自动管理内存: Qt 的内存管理机制允许通过设置父子关系(例如,将 sender 和 receiver 的父对象设置为 this),由 Qt 自动管理对象的生命周期。当父对象(如 MainWindow)被销毁时,Qt 会自动删除所有子对象,因此不需要手动调用 delete。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 通过将 parent 设置为 this,Qt 将自动管理 sender 和 receiver 的生命周期
SendSignal *sender = new SendSignal(this);
ReceiveSignal *receiver = new ReceiveSignal(this);
QPushButton *btn = new QPushButton;
btn->setText("close");
btn->setFixedSize(100, 50);
btn->setParent(this);
// 连接信号和槽
connect(btn, &QPushButton::clicked, sender, &SendSignal::exit);
connect(btn, &QPushButton::clicked, receiver, &ReceiveSignal::handleExit);
connect(sender, &SendSignal::exit, receiver, &ReceiveSignal::handleExit2);
qDebug() << "Signals and slots are connected";
}
MainWindow::~MainWindow()
{
// 不需要手动 delete sender 和 receiver,Qt 会自动管理这些对象
delete ui;
}