1

I am stuck in a problem of conception in C++ :

I made a Pool template class which does mostly the same than std::list but stores only objects and calls itself the constructor with placement new and the destructor of stored object.

Then I made an ObjectAllocator class which has a getObjectWithClass template method. I want to have this class like an interface so I can have a PoolObjectAllocator subclass which acts as a bridge between ObjectAllocator and Pool template class.

But there is no way to create getObjectWithClass as virtual because this is a template method.

template <class T>
class Pool {
  ...
public:
  T& getFreeObject();
  ...
}

class ObjectAllocator {
public:
  template <class T> T* getObjectWithClass(); // I need this method to be virtual
};

class PoolObjectAllocator : public ObjectAllocator {
  std::map<int, void *> pools;

public:
  template <class T> T* getObjectWithClass() {
    int type = T::GetType();

    Pool<T> *pool;
    if (this->pools.find(type) == this->pools.end()) {
      pool = new Pool<T>();
      pools[type] = pool;
    } else {
      pool = static_cast<Pool<T> *>(pools[type]);
    }

    return &pool->getFreeObject();
  };
};

// Later in the program :
ObjectAllocator *objectAllocator = myObject.getObjectAllocator();
objectAllocator->getObjectWithClass<OneClass>();

// Because the above line call a non virtual method, the method called is ObjectAllocator::getObjectAllocator and not PoolObjectAllocator::getObjectAllocator even if the objectAllocator is a PoolObjectAllocator.

I can't find a way to get this working, somebody could help me ? Thanks

Johnmph
  • 3,391
  • 24
  • 32
  • I know this is a duplicate, but I can't find the best similar question. But this question has been asked a few times. For example: http://stackoverflow.com/questions/15592424/how-to-design-around-the-limitation-that-templated-member-functions-cant-be-vir?rq=1virtual – Manu343726 Aug 10 '13 at 12:16
  • Thank you but I can't figure how can I implement the double dispatch solution in my problem. – Johnmph Aug 10 '13 at 14:12
  • 2
    You cannot do that in C++. Double dispatch won't work here. Try separating memory allocation from object creation, such that your allocation function allocates only raw memory. Thus there's no need for it to be templatized. The object creation function is templatized, it uses the allocation function but isn't virtual itself. – n. m. could be an AI Aug 10 '13 at 15:36
  • This question is pretty similar: http://stackoverflow.com/questions/17038434/pimpl-to-make-template-coding-less-cluttered – willj Aug 10 '13 at 17:11
  • @n.m.: Thank you, I am not very happy to separate memory allocation from object creation but I don't have the choice. I am too used with Objective-C... – Johnmph Aug 10 '13 at 21:57
  • Having a templated object creator that calls a virtual memory allocator is probably the best solution, but if you really don't like it you can template the ObjectAllocater *class* (and all its subclasses). If you think about how templates and virtual functions are implemented in the compiler, you'll see how they don't directly go together. – dspeyer Aug 12 '13 at 18:28

0 Answers0