0

Suppose I have a template class such as:

template <class type, size>
class myTemplate

and I had an abstract base class:

class myDataType

and various derived classes

class subDataType1 : public myDataType
class subDataType2 : public myDataType
           ...
class subDataTypeN : public myDataType

What I WANT to do, is call:

 myTemplate<myDataType, size> myObject;

However, this obviously doesn't work, because inside the template, I would be instantiating an object of an abstract class. Basically, I want the template to work with either of my derived classes, but I don't know how to mechanize this (coming from Java where "solutions" or workarounds such as type wildcards and "Object", for example, may have allowed me to at least get past the compiler's checks).

What I really want, is without altering my template class, allow multiple data types without instantiating multiple objects of my template class.

I should mention that I'm aware that the solution to this likely involves a call such as:

 myTemplate<myDataType*, size> myObject

But I'll likely need more details than that, as I'm new to C++ (I don't know what I don't know).

repeat
  • 18,496
  • 4
  • 54
  • 166
Chris Mauer
  • 176
  • 1
  • 8
  • Pretty broad. It's hard to make good suggestions without a concrete use case. You could allow any class and then use a `static_assert` to ensure at compile time that the class provided is a child of `myDataType`. Looking for a good duplicate. Some information here: https://en.cppreference.com/w/cpp/types/is_base_of and https://en.cppreference.com/w/cpp/language/static_assert – user4581301 Jul 19 '18 at 22:19
  • Here we go: [How to ensure that the template parameter is a subtype of a desired type?](https://stackoverflow.com/questions/7020292/how-to-ensure-that-the-template-parameter-is-a-subtype-of-a-desired-type). I'm not sure this is a duplicate, but it is a direction worth investigating. – user4581301 Jul 19 '18 at 22:22
  • Side note: Worth [reading about Object Slicing](https://stackoverflow.com/questions/274626/what-is-object-slicing) so you can avoid that nasty little shock when migrating from Java. – user4581301 Jul 19 '18 at 22:35
  • Also this [Why doesn't polymorphism work without pointers/references?](https://stackoverflow.com/questions/15188894/why-doesnt-polymorphism-work-without-pointers-references) – n. m. could be an AI Jul 20 '18 at 07:45
  • I can't provide my exact code due to IP restrictions, but maybe it would help if I provided more background/motivation for what I want to do. I am writing embedded code, dealing with a circular buffer. In my case, myTemplate is a circular buffer, and at compile time, it reserves "size" number of "myDataType" blocks. Now, because I'm working with embedded, I cannot simply instantiate several circular buffers (one for each child class), because I'm very limited on memory. I basically just want my single circular buffer to accept any subDataTypen. – Chris Mauer Jul 20 '18 at 12:58

2 Answers2

0

I don't quite understand what you are asking, but if you need a quick work around instead of creating the class as abstract one of the cool features in c++ is virtual vs. pure virtual. If you leave your functions as virtual you will need to provide a definition for the function. if you make them pure virtual you will have to define them in inherited classes.

Here is what it looks like:

template <class type, size>
class myTemplate
{
    public:
    virtual void foo();
    myTemplate(){};

};

void myTemplate::foo()
{
}

This allows the function foo to be overwritten by inherited classes without throwing compiler errors for un defined abstract classes.

  • In my example, I referred to "myDataType" as an abstract class. One of the caveats with Java is the distinction between Interface classes and abstract classes. With C++ (correct me if I'm wrong), there is no distinction between Interface and Abstract class, but there is a distinction between methods in an interface and methods in an abstract class (pure virtual function and virtual function, respectively). In my case, my abstract class only contains virtual functions, so it would be analogous to Java's abstract classes. I'm just looking to allow multiple data types into my template. – Chris Mauer Jul 20 '18 at 13:24
0

Coming from Java you need to understand that templates in C++ are not like generics in Java, more precisely templates are compile-time generics.

Everything that has something to do with a template or is a template exists only at compile-time as such when you do things like myTemplate<myDataType, size> myObject; there are actually two things that happen:

1.At compile-time when myDataType and size are substituted to the template, which in turn is instantiated to create a type. This type's name is myTemplate<myDataType*, size> and is the only this is the type with which you work at run-time.

2.At run-time the created type (myTemplate) is instantiated in order to create an object of that type.

What we can note from this is that a template instantiated with different template arguments will produce totally different types available at run-time which will not have any relationship between them, the relationship existing only at compile time. This is in contrast to how generics work in java where the generic argument is casted to Object at compile time and later, at run-time is casted to the actual type.

Hope this helped shed some light on C++ templates.

Petok Lorand
  • 955
  • 6
  • 15
  • Ah, that makes a lot of sense. Given that, I've got a logical error in my architecture. I'm not sure how to fix it though; is there a way to restructure my parent/child class relationship so that each of my child classes are of the same type? For instance, maybe an abstract class won't work for me, but there might be another way to format my parent class such that my child-classes can all be of type "myDataType". – Chris Mauer Jul 20 '18 at 12:49
  • I thought of a way to collapse my child classes into the parent classes, and it looks like my code is now compiling correctly. I'm accepting this as an answer because it made me realize my architectural error. – Chris Mauer Jul 20 '18 at 13:35