3

(C++/Qt) QObject へのスマート ポインターがあります。QWeakPointer としましょう。なんらかの外部的な理由 (別のオブジェクトで発生する可能性があるもの、またはイベントが原因で発生する可能性があるもの) により、指定されたオブジェクトが破棄される可能性があります。私はスマート ポインターを持っているので、ダングリング リファレンスはないので問題ありません。しかし、ポインターが null かどうかを常に確認する必要があります。

これを常にチェックしないようにするためにヌルパターンを使用することを考えていますが、QObjectでこれが可能かどうか、または便利かどうかはわかりません。ポインタがオブジェクトを指し、それが破壊された場合、スマートポインタはその指し示したオブジェクトをnullオブジェクトに変更するという考え方です。これは良い考えですか、それとも忘れて、ポインターが常に NULL かどうかを確認する必要がありますか?


例を示しましょう。ツールを使用して作業を行うワーカーがいます。

class Worker : public QObject
{
    Q_OBJECT

public:
    Worker(QObject *parent = 0);
    void work()
    {
        if(m_tool)
            m_tool->use();
        emit workCompleted();
    };

signals:
    workCompleted();

public slots:
    void setTool(QWeakPointer<Tool> tool);

private:
    QWeakPointer<Tool> m_tool;
};


class Tool : public QObject
{
    Q_OBJECT

public:
    Tool();

public slots:
    void use() =0;
};


class Screwdriver : public Tool
{
    Q_OBJECT

public:
    Screwdriver() : Tool();

public slots:
    void use()
    {
        // do something
    };
};


class Hammer : public Tool;
class Saw : public Tool;
...

この場合、ツールはライブラリのパブリック ドメイン オブジェクトであり、ワーカーによって使用されます。私はそのようなライブラリを開発しています。そのため、作業員はドライバーを使用していますが、壊れて破損します。問題ない:

if(m_tool)
    m_tool->use();
emit workCompleted();

m_tool は 0 なので、単に何もしません。ただし、毎回 null ではないことを確認する必要があります。

NullTool オブジェクトがあるとします。

class NullTool : public Tool
{
    Q_OBJECT

public:
    NullTool() : Tool();

public slots:
    void use()
    {
        // does nothing
    };
};

ツールが破棄されると、ポインターはスマートになり、NullTool インスタンスを指す必要があることを認識します。したがって、Worker::work() は次のように実装できます。

void Worker::work()
{
    m_tool->use();
    emit workCompleted();
};

m_tool->use() は何もしない NullTool で呼び出されるため、ポインタが null でないことを確認する必要はありません。

これは良い考えですか?Qtが提供するスマートポインタクラスで可能ですか、それともQWeakPointerをサブクラス化する必要がありますか?

4

3 に答える 3

3

null オブジェクト パターンは、値のようなクラスに最も適していると思います。例としては、QString や QVariant があります。if ( str && !str->isEmpty() ) のようなコードは必要なく、単に if ( !str.isEmpty() ) を実行します。値ではないが「ID」を持つQObjectsの場合、これが役立つとは思いませんでした。

于 2010-08-31T09:29:52.273 に答える
0

私はあなたのユースケースを明確に理解していませんが、QObjectからの次のシグナルを接続することにより、オブジェクトが破壊されたときにプログラムにシグナルを送ることができます。

void destroyed ( QObject * obj = 0 );
于 2010-08-31T08:15:36.287 に答える
0

あなたの考えには何の問題もありません。毎回ポインターをチェックする作業と比較して、実装にかかる作業を比較するだけです。ポインターを 10.000 回チェックしてみましょう。アプローチを使用することをお勧めします。補足: null オブジェクト パターンは、Tool::use()副作用がまったくないという事実に依存しています。

ポリモーフィックに で置き換えるときに、で起こりうる副作用がTool::use()邪魔にならないように注意してくださいNullTool::use()。言い換えれば、リスコフの置換原則を破らないように注意してください。

于 2010-09-05T03:55:39.037 に答える