我总是使用下面的代码连接到sqlite数据库。出于某些原因,我决定以使用*QSqlDatabase
而不是QSqlDatabase
的方式重写它。
我所做的只是在我的旧代码前面使用&
( Line_12 )。
但代码在第6行中崩溃。
无论如何,有人给了我 line_14 并且它有效。
所以...我无法理解我的第一个代码和为什么建议代码出错 它有效。
Foo::Foo(QString path_="db_path_name") {
InitialDataBase(path_);
bool isOpened = db->open();
if(!isOpened) exit(1);
else
queryExecutor = new QSqlQuery(*db); // --> Line_6
}
void Foo::InitialDataBase(QString path_) {
// Line_12 => DOESN'T WORK
db = &(QSqlDatabase::addDatabase("QSQLITE"));
// Line_14 => WORK
db = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE"));
db->setHostName("localhost");
db->setDatabaseName(path_);
db->setUserName("admin");
db->setPassword("admin");
}
答案 0 :(得分:0)
在第12行中,您将获取addDatabase()
返回的QSqlDatabase对象的地址。该对象是临时的,并在声明结束后立即销毁(第12行之后)。因此,您最终会得到一个悬空指针,即指向已删除对象的指针。
取消引用悬空指针是未定义的行为。在实践中,它通常会崩溃。
在第14行中,在堆上创建了一个新的QSqlDatabase对象,创建了从addDatabase()返回的临时QSqlDatabase对象的副本。这里调用复制构造函数QSqlDatabase(const QSqlDatabase&)。临时对象被销毁,但堆上的副本仍然存在。请注意,您必须稍后删除db
,否则最终会导致内存和资源泄漏(打开数据库连接)。
为什么你在这里使用指针?特别是作为初学者,它会导致崩溃和泄漏,如本例所示;)