3

Qtネットワーク メッセージを受信し、それをスマート ポインターによって管理される Google protobuf にデコードするC++ コードのセクションがあります。この関数は、protobuf の最小限の構造解析を行って、オプションのメッセージ フィールドが存在するかどうかを確認し、メッセージの特定の部分が存在する場合はシグナルをディスパッチします。

現在、これらのシグナルには、参照カウントを利用して、メッセージ全体を含むスマート ポインターのコピーが含まれています。ただし、ダウンストリーム ハンドラーが protobuf 全体を再解析する必要がないように、スマート ポインターをメッセージの特定のセクションにディスパッチしたいと考えています。関連するメッセージ セクションへの新しいスマート ポインターを単純に作成することはできません。これは、新しいポインターが範囲外になると、そのセクションを解放しようとするためです。

いくつかの安全チェックを省略して、これを説明する試み:

void Interface::processProtobuf(QByteArray const & networkData) {

    QSharedPointer<proto_message> msg(new proto_message);

    msg->ParseFromArray(networkData.data(), networkData.length());

    if (msg->has_configuration()) {

        // This will eventually attempt to free, thus causing corruption
        // of msg.
        QSharedPointer<config_message> cfg(msg->mutable_configuration());
        emit configurationChanged(cfg);

        // I resorted to this, which forces the receiver to re-parse
        // the data structure (which might be expensive for a deeply-nested
        // message) to get the desired 'configuration' pointer.
        emit configurationChanged(msg);
    }
}

これを行うには、すべてのサブと親がなくなるまでデータデストラクタが呼び出されないように、親ポインタの参照カウントを継承 (およびインクリメント) する「関連する」サブポインタを作成する方法が本当に必要です範囲。この機能は、標準のスマート ポインターの実装の 1 つで利用できますか? それとも、不要な特殊なケースを作成しましたか? 私が見つけた最も近いものはQt'sQSharedDataPointer<>ですが、サブポインターを作成する場合には役に立たないと思います。

Qtソリューションは必要ありません。私の回避策は私の現在のケースではうまくいくので、これはより学術的な質問でした。

4

1 に答える 1

6

std::shared_ptr(またはC++11 を持っていない場合) には、共有ポインターとboost::shared_ptrポインターを取るコンストラクターがあります。構築された共有ポインタは を指しますが、所有権を と共有します。これはあなたが必要とするものです。rp*pr

コンストラクタの署名は

template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;
于 2012-12-11T16:45:39.350 に答える