Question

I have a custom memory allocator which uses placement new. I then have a class that has a private constructor, and when I try to use my memory allocator it complains about the constructor being private.

Here is my function that allocates the memory and calls constructor using placement new:

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

Here is the class I want to allocate:

/* 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));
    }

As mentioned, the error is error C2248: 'Mesh::Mesh' : cannot access private member declared in class 'Mesh' Is there nice way around this?

Was it helpful?

Solution

Option 1: Make the custom allocator a friend of your class.

Option 2: Delegate the actual allocation job in the custom allocator to a non-member function, and make that specific non-member function a friend of your class.

Option 2b: Delegate the actual allocation job in the custom allocator to a non-member function, and specialize the non-member function to call Mesh::InitializeMesh (or what have you) instead of Mesh::Mesh.

Option 3: Create a version of AllocateObject that also takes an initialization functor, allowing the caller to pass in how the memory block is to be initialized. The default initialization functor would take any number of args and call placement new. The one you'd pass in in this case might do the same (but be a friend of the class), or it might be a pointer to some static method in Mesh, or what have you.

OTHER TIPS

The typical case for using private constructor is that the class designer don't want "typical" construction of the class. In this particular case, it would seem that the owner of the class wants you to use Mesh::CreateMesh - maybe you could just modify that to use your allocator directly - rather than via a template?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top