If you are relying on the parent/child relationship for your memory management, 
then you will be clear as long as your “parentObject” has not been deleted.

However, if you need your model to live longer than the object, I would use a 
std::shared_ptr and pass that around.

Scott

From: Interest [mailto:interest-bounces+scott=towel42....@qt-project.org] On 
Behalf Of Hao Hu
Sent: Friday, March 11, 2016 11:16 AM
To: interest@qt-project.org
Subject: [Interest] Dangling QSqlTableModel Pointer

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
_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

Reply via email to