Qtスマートポインター-QSharedPointer



Qt Smart Pointer Qsharedpointer



記事のディレクトリ

序文

QtスマートポインターQSharedPointerは、C ++のstd :: shared_ptrと同じ機能を持ち、その適用範囲は前に述べたものよりも広くなっています。 QPointerQScopedPointer より広範囲。

QSharedPointer

QSharedPointerは、QScopedPointerと同様に、ヒープ上のnew演算子によって割り当てられた動的オブジェクトをラップする共有ポインターですが、参照カウントスマートポインターを実装します。つまり、QScopedPointerとは異なり、QSharedPointerは自由にコピーして値を割り当て、どこでも共有できるため、QSharedPointerをコンテナ要素として使用することもできます。



いわゆるカウントポインタ、つまり内部QSharedPointerは、内部QSharedPointerが所有するメモリリソースを指します。たとえば、3つのQSharedPointersが同時にメモリリソースを指している場合、カウント3は、参照カウントが0に低下することを認識してから、メモリを自動的に解放します。 。

QSharedPointerはスレッドセーフであるため、QSharedPointerオブジェクトを同時に変更するスレッドが複数ある場合でもロックする必要はありません。 QSharedPointerはスレッドセーフですが、QSharedPointerが指すメモリ領域はスレッドセーフではない可能性があります。したがって、複数のスレッドは、QSharedPointerが指すデータを変更するときにロックも考慮する必要があります。



公式の例を見てみましょう:

static void doDeleteLater(MyObject *obj) { obj->deleteLater() } void otherFunction() { QSharedPointer obj = QSharedPointer(new MyObject, doDeleteLater) // continue using obj obj.clear() // calls obj->deleteLater() }

この例では、カスタム削除のために関数が渡されます。

メンバー関数を直接使用することもできます。



QSharedPointer obj = QSharedPointer(new MyObject, &QObject::deleteLater)

QSharedPointerは非常に使いやすく、通常のポインターと同じように直接使用されます。作成後すぐに使用でき、後で使用することはありません。

私自身が書いた簡単な例を見てみましょう。

class Student : public QObject { Q_OBJECT public: Student(QObject * parent = nullptr) ~Student() } class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0) ~Widget() private: QSharedPointer m_pStudent } #include 'widget.h' #include Widget::Widget(QWidget *parent) : QWidget(parent) { qDebug() << __FUNCTION__ m_pStudent = QSharedPointer(new Student()) } Widget::~Widget() { qDebug() << __FUNCTION__ } Student::Student(QObject *parent): QObject (parent) { qDebug() << __FUNCTION__ } Student::~Student() { qDebug() << __FUNCTION__ }

実行後にウィンドウを閉じ、出力:

Widget Student ~Widget ~Student

ご覧のとおり、studentオブジェクトは自動的に解放されます。

話す価値がある

QtのQObjectオブジェクトツリーシステム(親と子)は誰もが知っています。オブジェクトの作成時に親オブジェクトが指定されている場合、オブジェクトを手動で解放する必要はなく、親オブジェクトはリソースのリサイクルを行います。スマートポインタ関連のデータをクエリすると、スマートポインタとQObjectオブジェクトツリーシステムの組み合わせを紹介する記事が表示され、プログラムがクラッシュします。 記事はこちら しかし、これは6年前のブログです。私はそれを試しましたが、結果はクラッシュを示しませんでした:

上記の例でも、変更は次のとおりです。

m_pStudent = QSharedPointer(new Student(this))

親オブジェクトは、新規の場合に指定されます

実行後にウィンドウを閉じるのは正常です。 Qt5.11.1を使用しています

近年のQtアップデートでこの問題が解決したことを説明します。そうすれば、使用する過程であまり注意を払わず、自信を持って使用することができます。

OK、その他のドキュメント、リファレンス 公式紹介