长期以来,我一直在使用旧的 C++ 进行编程,因为我和我的团队从未决定升级到现代编程实践(我承认,部分原因也是我的错),所以最近我一直在学习 C++11, C++14、C++17 所以我可以掌握它的窍门,我遇到的第一件事是 std::unique_ptr,在我看来它使用起来很棒,但我仍然对将它与 Qt 一起使用感到困惑,因为我在 Qt 中读到过,如果我创建一个 QObject,它是另一个 QObject 的子级,如果父级被删除,则子级也将被删除,并且使用 std::unique_ptr 可能会导致双重删除。所以我想知道,这是正确的:
主窗口.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSqlQueryModel>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QSqlDatabase p_AppDB;
QSqlQueryModel *p_QueryModel;
};
#endif // MAINWINDOW_H
主窗口.cpp:
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "Dialog.h"
#include <QDebug>
#include <QSqlQuery>
#include <QSqlError>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
p_AppDB = QSqlDatabase::addDatabase("QSQLITE" , "test"); // Set Database connection driver + name
p_AppDB.setDatabaseName("AppDB.db"); // Set SQLite database file name
if(!p_AppDB.open()) // Open database and check if connection failed
{
qDebug() << "ERR: " << p_AppDB.lastError().text(); // Print out an error message
}
p_QueryModel = new QSqlQueryModel(this); // How do i avoid using 'new' here ?
QSqlQuery _Query(QSqlDatabase::database("test")); // Create a new QSqlQuery
_Query.prepare("SELECT * FROM Users"); // Prepare a simple query to select everything from the table 'user'
if(!_Query.exec()) // Execute query and check if the execution failed
{
qDebug() << _Query.lastError().text(); // Print out an error message
return; // Return if the execution failed
}
p_QueryModel->setQuery(_Query); // Set the QSqlQuery with its data to the QSqlQueryModel we created
ui->View_TableView->setModel(p_QueryModel); // Set the QSqlQueryModel with its data to the TableView
// TEST
auto dlg = std::make_unique<Dialog>(); // Create a new Dialog
dlg->exec(); // Execute (Display) the dialog
}
MainWindow::~MainWindow()
{
p_AppDB.close(); // Close the database connection
delete ui;
}
例如,在创建 QWidget 或其他任何东西时,我如何使用 std::unique_ptr 而不是使用旧的: QWidget *w = new QWidget(this);
我知道可能会出现一些错误,因为我已经有一段时间没有编程了,现在我又回到了 C++ 和 Qt,但我希望是否还有其他错误可以指出。
谢谢
简短的回答是你不能——QWidget 父/子所有权方案和智能指针不能互操作。你是对的,试图用智能指针控制它们通常会导致双重删除问题。
在某些情况下,您可以执行类似的操作std::unique_ptr<QWidget> ptr(new QWidget);
,并且QWidget
当unique_ptr
超出范围时对象将被删除,正如预期的那样 - 但 Qt 中的许多功能都基于遍历在您制作各种QWidget
'时组装的对象树s 是 otherQWidget
的孩子,所以通过智能指针管理小部件只有在该小部件永远不需要成为任何其他小部件的孩子时才实用。
所以:在 Qt-land 中,像 Qt API 那样做,并在适当的情况下使用传统的父子所有权方法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句