1

プレースメント new を使用するカスタム メモリ アロケータがあります。次に、プライベート コンストラクターを持つクラスがあり、メモリ アロケーターを使用しようとすると、コンストラクターがプライベートであると不平を言います。

これは、新しい配置を使用してメモリを割り当て、コンストラクターを呼び出す関数です。

template <class T, typename arg0>
inline T* AllocateObject(arg0& a0) { return new (InternalAllocate(sizeof(T))) T(a0); }

割り当てたいクラスは次のとおりです。

/* MeshPtr definition */
   typedef boost::shared_ptr<Mesh> MeshPtr;

/* Mesh defintion */
    class Mesh
    {
    public:
        static MeshPtr CreateMesh(IVertexBuffer* vertexBuffer);
        ~Mesh();

        IVertexBuffer* GetVertexBuffer();


    private:
        Mesh(IVertexBuffer* vertexBuffer);

        IVertexBuffer* mVertexBuffer;
    };


 MeshPtr Mesh::CreateMesh(IVertexBuffer* vertexBuffer)
    {
        return MeshPtr(HeapAllocator::GetDefaultHeapAllocator().AllocateObject<Mesh>(vertexBuffer), boost::bind(&HeapAllocator::DeallocateObject<Mesh>, &HeapAllocator::GetDefaultHeapAllocator(), _1));
    }

前述のように、エラーはerror C2248: 'Mesh::Mesh' : cannot access private member declared in class 'Mesh' これを回避する良い方法はありますか?

4

2 に答える 2

1

オプション 1: カスタム アロケータをクラスのフレンドにします。

オプション 2: カスタム アロケーターの実際の割り当てジョブを非メンバー関数に委任し、その特定の非メンバー関数をクラスのフレンドにします。

オプション 2b: カスタム アロケーター内の実際の割り当てジョブを非メンバー関数に委任し、非メンバー関数を特殊化してMesh::InitializeMeshMesh::Mesh.

オプション 3:AllocateObject初期化ファンクターも受け取るバージョンを作成し、呼び出し元がメモリ ブロックの初期化方法を渡すことができるようにします。デフォルトの初期化ファンクターは、任意の数の引数を取り、placement new を呼び出します。この場合に渡すものは、同じことを行う可能性があります (ただし、クラスのフレンドである)、または の静的メソッドへのポインターである可能性がMeshあります。

于 2012-12-29T13:06:39.987 に答える
0

プライベートコンストラクターを使用する典型的なケースは、クラス設計者がクラスの「典型的な」構築を望まない場合です。この特定のケースでは、クラスの所有者がMesh :: CreateMeshを使用することを望んでいるように見えます。おそらく、テンプレートを介さずに、アロケータを直接使用するように変更できますか?

于 2012-12-29T13:02:15.640 に答える