• Qt中使用QSqlDatabase::removeDatabase()的正确方法


    如果你用过Qt的QSqlDatabase的话,多半会对下面的警告信息感兴趣:

    QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all

    queries will cease to work.

    意思是说,还有某查询引用默认数据库连接"qt_sql_default_connection"。

    如果忽略该警告,Qt官方文档里也写了,可能会出现内存泄漏:

    Warning: There should be no open queries on the database connection when this function is called,

    otherwise a resource leak will occur.

    还是不出现这个警告的好。怎么把它弄没了呢?我把一切外围的对象都排除了:仅建立一个连接,打开它,然后关闭连接,调用removeDatabase()。居然还有警告!问题已经锁定在我关闭连接的语句上:

    QSqlDatabase::removeDatabase(QSqlDatabase::database().connectionName());

    默认连接的名字也是默认的,需要通过connectionName()函数获得。这样写貌似没什么问题,后来调试发现,QSqlDatabase::database()静态函数实际上使默认连接的引用计数+1。上述句子相当于:

    QSqlDatabase db = QSqlDatabase::database();//获得实例。
    
    QString name = db.connectionName();//获得默认连接名。
    
    QSqlDatabase::removeDatabase(name);//删除默认连接。

    这样,问题就清晰了,db获得了一个引用,此时引用计数为2。在调用removeDatabase()时,db对象并没有被删除,默认连接的引用计数仍为2,于是报告警告信息。

    我们只需将其改为:

        QString name;
    
        {
    
            name = QSqlDatabase::database().connectionName();
    
        }//超出作用域,隐含对象QSqlDatabase::database()被删除。
    
        QSqlDatabase::removeDatabase(name);

    问题就解决了!

    如果直接打默认连接名的话,代码就简单多了,不过名字不太好打(再说了,万一Qt把默认连接名改了呢!):

    QSqlDatabase::removeDatabase("qt_sql_default_connection");//不推荐。

     

    ================下面是官方文档摘录================

    Warning: There should be no open queries on the database connection when this function is called, otherwise a resource leak will occur.

    Example:

     // WRONG
    
     QSqlDatabase db = QSqlDatabase::database("sales");
    
     QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
    
     QSqlDatabase::removeDatabase("sales"); // will output a warning
    
     // "db" is now a dangling invalid database connection,
    
     // "query" contains an invalid result set

    The correct way to do it:

     {
    
         QSqlDatabase db = QSqlDatabase::database("sales");
    
         QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
    
     }
    
     // Both "db" and "query" are destroyed because they are out of scope
    
     QSqlDatabase::removeDatabase("sales"); // correct
  • 相关阅读:
    Java内存模型详解
    《深入理解java虚拟机》读书笔记十一——第十二章
    《深入理解java虚拟机》读书笔记十——第十一章
    《深入理解java虚拟机》读书笔记九——第十章
    《深入理解java虚拟机》读书笔记八——第九章
    《深入理解java虚拟机》读书笔记七——第八章
    《深入理解java虚拟机》读书笔记六——第七章
    《深入理解java虚拟机》读书笔记四——第五章
    a标签添加onclick事件
    Vi||Vim显示行号,自动缩进,调整tab键宽度技巧
  • 原文地址:https://www.cnblogs.com/codingmylife/p/1722404.html
Copyright © 2020-2023  润新知