4

C ++ / CLIでは、マネージド.NETジェネリックコレクションにネイティブC++クラスへのポインターを配置することはできません。

class A {
public:
    int x;
};

public ref class B {
public:
    B()
    {
        A* a = GetPointerFromSomewhere();
        a->x = 5;
        list.Add(a);
    }
private:
    List<A*> listOfA; // <-- compiler error (T must be value type or handle)
}

許可されていません。もちろん使用することもできますstd::vector<A*> list;が、ポインターを使用することによってのみlistマネージドクラスのメンバーを作成することができ、STLコンテナーへのポインターを使用するのは不自然に感じます。

ネイティブC++ポインターを.NETジェネリックに格納するための良い方法は何ですか?(ここではリソース管理には興味がありません。ポインターが指すオブジェクトは他の場所で管理されます)

4

1 に答える 1

7

私が使用している方法は、ポインターを管理値クラスでラップしてから、間接参照演算子をオーバーロードすることです。

template<typename T>
public value class Wrapper sealed
{
public:
    Wrapper(T* ptr) : m_ptr(ptr) {}
    static operator T*(Wrapper<T>% instance) { return instance.m_ptr; }
    static operator const T*(const Wrapper<T>% instance) { return instance.m_ptr; }
    static T& operator*(Wrapper<T>% instance) { return *(instance.m_ptr); }
    static const T& operator*(const Wrapper<T>% instance) { return *(instance.m_ptr); }
    static T* operator->(Wrapper<T>% instance) { return instance.m_ptr; }
    static const T* operator->(const Wrapper<T>% instance) { return instance.m_ptr; }
    T* m_ptr;
};

その後、次のようにポインタを自然に使用できます。

public ref class B {
public:
    B()
    {
        A* a = GetPointerFromSomewhere();
        a->x = 5;
        list.Add(Wrapper<A>(a));
        Console.WriteLine(list[0]->x.ToString());
    }
private:
    List<Wrapper<A>> listOfA;
}

どんな改善も歓迎します...

于 2012-07-03T09:47:16.147 に答える