Qt QpointerとQSharedPointerの使用例

3640 ワード


 
ネット上で多くのQtの中でQpointerとQSharedPointerについて調べて、大部分は公式の例で、ここでは実際に対象の中で使用します.
まずQpointerとQSharedPointerの簡単な使い方を紹介します.
QPointer
QPointer can only point to QObject instances. It will be automatically set to nullptr if the pointed to object is destroyed. It is a weak pointer specialized for QObject. 
簡単に理解すると、QObjectを指すためにパッケージを提供し、C++の従来のポインタと同じ方法を提供しているが、「野」ポインタを避けることができる.大胆に使えます.
QObject *obj = new QObject;
QPointer pObj(obj);
delete obj;
Q_ASSERT(pObj.isNull()); // pObj will be nullptr now

QSharedPointer
A reference-counted pointer. The actual object will only be deleted, when all shared pointers are destroyed. Equivalent to std::shared_ptr.
簡単に言えば使わないで、解放しました.
int *pI = new int;
QSharedPointer pI1(pI);
QSharedPointer pI2 = pI1;
pI1.clear();
// pI2 is still pointing to pI, so it is not deleted
pI2.clear();
// No shared pointers anymore, pI is deleted

総合例
1.personオブジェクトを作成します.ここでは、メンバーnameが1つしかないことを簡略化します.
 
Person.h
class Person :  public QObject
{
    Q_OBJECT
public:
    Person(const QString &name, QObject *parent = nullptr);
    virtual ~Person();
    QString name() const;
    void setName(const QString &name);

private:
    QString m_name; //   
};

Person.cpp
Person::Person(const QString &name, QObject *parent) : QObject(parent)
{
    m_name = name;
    qDebug() << "create a person: " << m_name;
}


Person::~Person()
{
    qDebug() << "delete a person: " << m_name;
}

QString Person::name() const
{
    return m_name;
}

void Person::setName(const QString &name)
{
    m_name = name;
}

説明時にオブジェクトを解放することをより理解するために、MainWindowクラスを構築します.次はコードです.
 
ヘッダファイル
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    QList> m_persons;
    QSharedPointer m_person;

};
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    qDebug() << m_person;
    m_persons.append(new Person("person1"));
    m_persons.append(new Person("person2"));


    QPointer tmp = new Person("tmp");
    // need delelet tmp
    delete tmp;
    QSharedPointer sharedPerson(new Person("sharedPerson"));
    m_person = sharedPerson;
}

MainWindow::~MainWindow()
{
    qDebug("call ~Mainwindow");
    //       children
    qDeleteAll(m_persons);
    m_persons.clear();
    // m_person    ,       

}

 
最後の印刷結果は
QSharedPointer(QObject(0x0))
create a person:  "person1"
create a person:  "person2"
create a person:  "tmp"
delete a person:  "tmp"
create a person:  "sharedPerson"
call ~Mainwindow
delete a person:  "person1"
delete a person:  "person2"
delete a person:  "sharedPerson"

解析の結果、Qpointerを使用するQListでは、リリース時にQListで管理し、qDeleteAll()を呼び出し、personを呼び出さない構造関数を呼び出さず、通常使用するQObjectオブジェクトポインタにはparentがあるので、qDeleteAllをわざわざ呼び出す必要はありません.そしてQpointerを単独で検証するためにtmpを生成し,これはdeleteを必要とする.他の解放が確定しない場合はtmpを呼び出す.isNull()判断してみます.
m_PersonはQSharedPointerを指し、この使用は普通のオブジェクトのようにm_を呼び出していません.person.clear()は、複数のインスタンスでm_を共有します.personはどこかで釈放を忘れる必要はない.
具体例は梱包しておきますhttps://download.csdn.net/download/luodanzhi/10772842
 
参照先:
[Qtメモリ管理(3)Qtのスマートポインタ](https://blog.csdn.net/yao5hed/article/details/81092152)