この記事では、QSharedPointerの「ライト」バージョンであるスマートポインターQScopedPointerについて説明します。 バージョン4.6で導入されたQScopedPointer。
ブーストでは、Qt-smartスマートポインターに類似しています:
QSharedPointer-ブースト:: shared_ptr
QWeakPointer-ブースト:: weak_ptr
QScopedPointer-ブースト:: scoped_ptr
例1
m_socketオブジェクトを削除せず、したがってアプリケーションが終了してもソケットは切断されない単純なプログラム:
class test_socket : public QTcpSocket { public: test_socket( QObject * parent ) : QTcpSocket( parent ) { } virtual ~test_socket( ) { qDebug( ) << "~test_socket"; } }; class test_scop_ptr_obj : public QObject { Q_OBJECT test_socket * m_socket; public: test_scop_ptr_obj( ) : m_socket( new test_socket( 0 ) ) { m_socket->connectToHost( "www.ru", 80 ); connect( m_socket, SIGNAL( stateChanged ( QAbstractSocket::SocketState ) ), SLOT( on_state_changed( QAbstractSocket::SocketState ) ) ); } virtual ~test_scop_ptr_obj( ) { qDebug( ) << "~test_scop_ptr_obj"; } private Q_SLOTS: void on_state_changed( QAbstractSocket::SocketState socket_state ) { qDebug( ) << socket_state; } }; int main( int argc, char** argv ) { QCoreApplication a( argc, argv ); test_scop_ptr_obj obj; QTimer::singleShot( 3000, &a, SLOT( quit( ) ) ); return a.exec( ); }
プログラムを開始すると、次の出力が得られます。
QAbstractSocket :: ConnectingState
QAbstractSocket :: ConnectedState
〜test_scop_ptr_obj
例2
次に、行を変更します。
: m_socket( new test_socket( 0 ) )
行ごと:
: m_socket( new test_socket( this ) )
そして結論を得る:
QAbstractSocket :: ConnectingState
QAbstractSocket :: ConnectedState
〜test_scop_ptr_obj
〜test_socket
例3
スマートポインターを追加すると、クラスtest_scop_ptr_objは次のようになります。
class test_scop_ptr_obj : public QObject { Q_OBJECT QScopedPointer< test_socket > m_socket; public: test_scop_ptr_obj( ) : m_socket( new test_socket( 0 ) ) { m_socket->connectToHost( "www.ru", 80 ); connect( m_socket.data( ), SIGNAL( stateChanged ( QAbstractSocket::SocketState ) ), SLOT( on_state_changed( QAbstractSocket::SocketState ) ) ); } virtual ~test_scop_ptr_obj( ) { qDebug( ) << "~test_scop_ptr_obj"; } private Q_SLOTS: void on_state_changed( QAbstractSocket::SocketState socket_state ) { qDebug( ) << socket_state; } };
結論が得られます。
QAbstractSocket :: ConnectingState
QAbstractSocket :: ConnectedState
〜test_scop_ptr_obj
〜test_socket
QAbstractSocket :: UnconnectedState
分析
この例ではメモリリークが発生するため、例1は興味深いものではありません。
例2と3は、以前に割り当てられたメモリを解放する技術が異なります。 どちらの例でも、test_socketクラスのオブジェクトは削除されますが、3番目の例では、〜test_scop_ptr_objデストラクターが呼び出された後にon_state_changed関数が呼び出されますが、これはエラーです。 子を削除する前に、親オブジェクトは信号とスロットを切断します。したがって、例2では、stateChanged信号はtest_scop_ptr_objオブジェクトに到達しません。
まとめ
例3のエラーを修正するには、削除されたオブジェクトのシグナルの切断をtest_scop_ptr_objデストラクタに追加する必要があります。
virtual ~test_scop_ptr_obj( ) { m_socket->disconnect( ); qDebug( ) << "~test_scop_ptr_obj"; }
この場合、出力は例2と同じになります。