2

次のようなライブラリから提供されるクラスがあります。

template <typename T>
class TypedClass
{
public:
    typedef typename boost::shared_ptr<TypedClass<T> > Ptr;

    T m_data;
    T* m_pointer_data;
};

この特定のアーキテクチャで int と float が常に同じサイズ (およびアラインメント) であることを喜んで受け入れると仮定すると、これは私には有効に思えます。

TypedClass<int>* int_object = new TypedClass<int>();

TypedClass<float>* float_object = reinterpret_cast<TypedClass<float>* >(int_object);

今、boost shared_ptrs を使用して同じことを達成しようとしていますが、これを思いつきました:

TypedClass<int>::Ptr int_object = TypedClass<int>::Ptr(new TypedClass<int>());

void* int_object_void_pointer = reinterpret_cast<void*>(int_object.get());

TypedClass<float>::Ptr float_object(reinterpret_cast<TypedClass<float>*>(int_object_void_pointer));

これは問題なく動作するように見えますが、共有ポインタをこのように使用すると、オブジェクトが 2 回削除されるので、避けたいと思います。

「TypedClass」はサードパーティ ライブラリの一部であり、このライブラリはすべての内部機能に共有ポインタを使用するため、この形式のデータが必要であることに注意してください。私は以前にこの問題を boost enable_shared_from_this から継承して解決しましたが、ここでは不可能です。

これは、新しい型で新しいオブジェクトを割り当てることなく、同じサイズのデータ​​型に対して同じオブジェクトを再利用しようとする単純な手法です。

提案を歓迎します。

4

5 に答える 5

5

shared_ptr<T>興味深いオーバーロードされたコンストラクターがあります。

template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p);

r基本的に、これは、保持することを除いて、からデリータと refcounting を取る shared_ptr を構築しますp

次のように使用できます。

TypedClass<int>::Ptr int_object = TypedClass<int>::Ptr(new TypedClass<int>());

TypedClass<float>::Ptr float_object(int_object,reinterpret_cast<TypedClass<float>*>(int_object.get()));

編集

Boost >= 1.53.0 を使用している場合は、 もありboost::reinterpret_pointer_castます。したがって、次のように書くことができます。

TypedClass<float>::Ptr float_object = boost::reinterpret_pointer_cast<TypedClass<float> >(int_object);
于 2013-09-05T02:40:21.000 に答える
1

ブースト ポインター キャストを使用できます。これは非常に見苦しい解決策ですが、少なくとも参照カウントはこの方法で機能します。

TypedClass<int>::Ptr int_object = TypedClass<int>::Ptr(new TypedClass<int>());
TypedClass<float>::Ptr float_object = boost::static_pointer_cast<TypedClass<float>>(boost::shared_ptr<void>(int_object));
于 2013-09-04T08:34:24.230 に答える
1

サードパーティ ライブラリから新しい型の新しいオブジェクトを割り当てることなく、同じサイズのデータ​​型に対して同じオブジェクトを実際に再利用しようとすると、選択肢が限られます。

  1. raw ポインターから shared_ptr を割り当てないでください。そうしないと、2 回削除され、セグメント フォールトが発生します。
  2. タイプ (shared_ptr) を再利用して、operator=(); で直接「コピー」できるようにします。または生のポインターを cat し、メモリの割り当て/削除に影響を与える変更を行わないようにします。

あなたの例として、私は以下のようなコードを提案します:

float* float_ptr = reinterpret_cast<float*>(&int_object->m_data);
// Do something with *float_ptr
// And never delete it!
于 2013-09-03T08:21:35.000 に答える
0

データへの参照を保持し、カウントが0のときに削除するため、共有ptrクラス自体を2つのパラメーターtypenameでオーバーロードする場合を除き、できないと思います。ただし、タイプから別のタイプに移動する必要があるため、ブーストshared ptr は、とにかくデータを解放したと考えます。

shared_ptr p=ptr; //ptr と p が同じ型の場合、ref を追加します。

タイプが同じでない場合は、内部データを取得してから解放します。

別の解決策は、boost::any を使用して、このコンテナに保持するすべてのデータを保持することです。

于 2013-09-02T19:25:02.957 に答える