Inheriting from a template class in C ++

Say we have an Area template class that has a member variable T area , a T getArea() and void setArea(T) member functions.

I can create an Area object of a certain type by typing Area<int> .

Now I have a Rectangle class that inherits the Area class. Since the Rectangle itself is not a template, I cannot type a Rectangle<int> .

How do I specialize the Area inherited type for Rectangle objects?

EDIT: Sorry, I forgot to clarify - my questions are whether it is possible to inherit an area without its specialization, so it is not inherited as Area of ​​ints, but how Area Rectangle can specialize types for.

+65
c ++ inheritance templates
Jan 10 2018-12-12T00:
source share
6 answers

For understanding patterns, this has the huge advantage of getting terminology directly, because the way you talk about them determines the way you think about them.

In particular, Area not a template class, but a class template. That is, it is a template from which classes can be generated. Area<int> is such a class (this is not an object, but, of course, you can create an object from this class in the same way as you can create objects from any other class). Another such class would be Area<char> . Note that these are completely different classes that have nothing in common except for the fact that they were created from the same class template.

Since Area not a class, you cannot extract the Rectangle class from it. You can get a class from another class (or several of them). Since Area<int> is a class, you can, for example, extract a Rectangle from it:

 class Rectangle: public Area<int> { // ... }; 

Since Area<int> and Area<char> are different classes, you can even extract them from both at the same time (however, when accessing members from them you will have to deal with ambiguities):

 class Rectangle: public Area<int>, public Area<char> { // ... }; 

However, you need to specify which classification to use when you define a Rectangle . This is true whether these classes are generated from the template or not. Two objects of the same class simply cannot have different inheritance hierarchies.

What you can do is make a Rectangle pattern. If you write

 template<typename T> class Rectangle: public Area<T> { // ... }; 

You have a Rectangle template from which you can get the Rectangle<int> class that comes from Area<int> , and another Rectangle<char> class that comes from Area<char> .

Perhaps you want to have one type of Rectangle so that you can pass all kinds of Rectangle to the same function (which itself does not need to know the type of region). Since the Rectangle<T> classes created by instantiating the Rectangle template are formally independent of each other, this does not work. However, you can use multiple inheritance here:

 class Rectangle // not inheriting from any Area type { // Area independent interface }; template<typename T> class SpecificRectangle: public Rectangle, public Area<T> { // Area dependent stuff }; void foo(Rectangle&); // A function which works with generic rectangles int main() { SpecificRectangle<int> intrect; foo(intrect); SpecificRectangle<char> charrect; foo(charrect); } 

If it is important that your overall Rectangle derived from a common Area , you can do the same trick with Area too:

 class Area { // generic Area interface }; class Rectangle: public virtual Area // virtual because of "diamond inheritance" { // generic rectangle interface }; template<typename T> class SpecificArea: public virtual Area { // specific implementation of Area for type T }; template<typename T> class SpecificRectangle: public Rectangle, // maybe this should be virtual as well, in case the hierarchy is extended later public SpecificArea<T> // no virtual inheritance needed here { // specific implementation of Rectangle for type T }; 
+163
Jan 10 2018-12-21T00:
source share
β€” -

Are you just trying to extract from Area<int> ? In this case, you do this:

 class Rectangle : public Area<int> { // ... }; 

EDIT: after finding out, it looks like you are actually trying to make a Rectangle template, and in this case the following should work:

 template <typename T> class Rectangle : public Area<T> { // ... }; 
+12
Jan 10 2018-12-12T00:
source share
 class Rectangle : public Area<int> { }; 
+8
Jan 10 2018-12-12T00:
source share

Make the Rectangle a template and pass the type name in Area:

 template <typename T> class Rectangle : public Area<T> { }; 
+6
Jan 10 2018-12-12T00:
source share

Rectangle must be a template, otherwise it is just one type. This cannot be a template, while its foundation is magical. (Its base could be instantiating a template, although you seem to want to keep the basic functionality as a template.)

+5
Jan 10 2018-12-12T00:
source share
 #include<iostream> using namespace std; template<class t> class base { protected: ta; public: base(t aa){ a = aa; cout<<"base "<<a<<endl; } }; template <class t> class derived: public base<t>{ public: derived(ta): base<t>(a) { } //Here is the method in derived class void sampleMethod() { cout<<"In sample Method"<<endl; } }; int main() { derived<int> q(1); // calling the methods q.sampleMethod(); } 
0
May 02 '17 at 11:08 a.m.
source share



All Articles