[Interest] Dangling QSqlTableModel Pointer

Hao Hu 0102uhh at gmail.com
Fri Mar 11 20:16:23 CET 2016


Hi All,

When using QSqlTableModel and the QTableView, the API provided (by the
documentation <http://doc.qt.io/qt-5/qsqltablemodel.html>) is:

    QSqlTableModel
<http://doc.qt.io/qt-5/qsqltablemodel.html#QSqlTableModel> *model =
new QSqlTableModel
<http://doc.qt.io/qt-5/qsqltablemodel.html#QSqlTableModel>(parentObject,
database);
    model->setTable("employee");
    model->setEditStrategy(QSqlTableModel
<http://doc.qt.io/qt-5/qsqltablemodel.html#QSqlTableModel>::OnManualSubmit);
    model->select();
    model->setHeaderData(0, Qt
<http://doc.qt.io/qt-5/qt.html>::Horizontal, tr("Name"));
    model->setHeaderData(1, Qt
<http://doc.qt.io/qt-5/qt.html>::Horizontal, tr("Salary"));

    QTableView <http://doc.qt.io/qt-5/qtableview.html> *view = new
QTableView <http://doc.qt.io/qt-5/qtableview.html>;
    view->setModel(model);
    view->hideColumn(0); // don't show the ID
    view->show();


But most of the time, I'll need to manipulate the data in the database
connected to the QSqlTableModel. Which means I need to pass the raw pointer
"model" around to different classes. For instance, I defined a class Foo
which has a data member that is a pointer of type QSqlTableModel *:

class Foo {
public:

    virtual void update();  // read up-to-date data from the database
protected:

    QSqlTableModel *m_model;  // it would be better to have
QSharedPointer<QSqlTableModel> ?}


So the reason for the Foo class to have a data member of type
QSqlTableModel is to read the up-to-date data from the data from the
database. However, this doesn't look good to me to have a raw pointer
passed around like this. Obviously I won't let my virtual destructor of Foo
to destruct this object pointed by "m_model" because it may be needed
somewhere else. And also, it would be hard to manage the memory since Foo
has no knowledge of whether the pointer is freed somewhere else.

So, instead of writing code like this, I changed the data member
"m_model"'s type to QSharedPointer<QSqlTableModel> and when creating the
object in the top level, I also wrapped the raw pointer with
QSharedPointer. Basically it looks like this:

int main(int argc, char *argv[]){
    /* create and open database "db" */

    if (db.open()) {
        ...
        QSharedPointer<QSqlTableModel> pModel =
QSharedPointer<QSqlTableModel>(new QSqlTableModel(NULL, db) );
        Foo foo(pModel);
        ...

        tableView->setModel(pModel);   // The problem is here
    }}


It's so disappointing when I saw the compiler was complaining about no
corresponding member functions for QTableView to accept the QSharedPointer
that points to the QSqlTableModel.

I'm just wondering why the QSqlTableModel is designed to be used like this
way? Wouldn't it be better to use a smart pointer here instead of using the
raw? If so, is it possible to add new member functions in the future that
will accept the QSharedPointer<QSqlTableModel> as the input argument type?


Thank you for your help!


Regards,
Hao
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20160311/cfbc2937/attachment.html>


More information about the Interest mailing list