I'm working on a template class. Not that it matters, but my goal is a list class that will use some static members to maintain a linked list of class objects. Each different class will have it's own list. Not only that, but each class will have a compile-time allocated pool of available instances of the object rather than pulling them from a common heap. I'm working on a bare-metal system with limited resources. Part of the reason for avoiding a heap is to avoid fragmentation in an embedded system that will run for long periods of time. Another part is determinism. I don't want the number of ObjectA allocated to interact with the number of ObjectB being allocated and I want a predictable number of each to be available. In real-time embedded systems, predictability and consistency are often more important than raw performance. I do this all the time in C but I'm trying to graduate to C++ while keeping the efficiencies of C.
Here's a pared-down example that illustrates the crux of my C++ problem.
template <class T>
class ListOf<T>
{
public:
static ListOf<T> *method();
};
I want to be able to derive classes that have all of the methods and properties of the ListOf template class plus additional "payload" properties. I thought I could do this by subclassing a class that is derived from the template:
class Something
{
// nothing here. This is only used to let me give a unique name to my derived class.
};
class ListOfSomething : public ListOf<Something>
{
int payloadProperty; // specific to the derived class
};
And I expect to be able to do this:
ListOfSomething *ptr;
ptr = ListOfSomething::method();
but the compiler tells me that I can't assign a ListOf* to a ListOfSomething* and I guess I can understand that. I'm asking to convert a base class pointer to a derived class pointer. I can work around it with a static cast like this
ListOfSomething *ptr;
ptr = static_cast<ListOfSomething *>ListOfSomething::method();
But that seems pretty clunky. Seems like the whole point of the template concept is to do stuff like this.
Maybe my whole approach is wrong. Referring to my broader goal, not to the specific casting problem, I know that I could add a pointer to T to my template class:
template <class T>
class ListOf<T>
{
public:
ListOf<T> *method();
T *payload;
};
class Something
{
int payloadProperty;
};
class ListOfSomething : public ListOf<Something>
{
};
but I was trying to avoid a level of indirection. With this method, I have to allocate the payload separately and dereference a pointer every time I want to access it. I am looking for some way to extend the ListOf class that is equivalent to just adding some more members to the class, effectively creating
class ListOfSomething
{
public:
ListOfSomething *method();
T payload;
};
but somehow encapsulating the list mechanics of allocation. deallocation, traversal, etc for reusability.