Inheritance with template classes - c++

I'm trying to figure out, how can I inherit from template class to template class. The problem is: I can't use protected members of Parent class.
Example:
template <class N>
class Parent {
protected:
N member;
public:
Parent(N aa){
member = aa;
}
};
class Child1: public Parent<int>{
public:
Child1(int a): Parent<int>(a) {
member += 1; // works
}
};
template<class Q>
class Child2: public Parent<Q>{
public:
Child2(int a): Parent<Q>(a) {
member += 1; // does not work (use of undeclared identifier)
}
};
How can I use "member" in the Child2 class?
Thanks for your time

You need to use this->member or Parent<Q>::member.
In the second case, member is a "dependent name" because the existence of member from the base class template Parent<Q> depends on the type of class Q in the template, whereas in the first example there is no dependent type, the compiler can statically analyze that Parent<int> contains member.

Related

Using structs of derived class y base template

I have a base template:
template <typename T>
class Base
{
public:
void method(T);
};
And a derived class:
class Derived: public Base<Derived::status_t>
{
public:
typedef struct
{
uint8_t value;
} status_t;
}
I'm have more derived classes, each one with it status_t specific struct. I want to use these structs in the base class, but the compiler give me an error:
Error[Pe070]: incomplete type is not allowed.
I suppose that the problem is that the struct is not defined in the moment that the base constructor is called. Is there any way to maintain the struct in the derived class and use it un the base template?
Thanks,

member initializer 'SuperClass' does not name a non-static data member or base class

I have a problem with some of my constructors. Both subclasses need to get the same classes (no super class), that is why these classes should be initialized in the super class:
template<typename T, typename S>
class SuperClass {
protected:
OtherClass <T> const& _class1;
OtherOtherClass <T> const& _class2;
SuperClass() {
}
SuperClass(OtherClass<T> const& class1, OtherOtherClass<T> const& class2)
: _class1(class1), _class2(class2)
{
// Alternative I tried:
// this->_class1 = class1;
// this->_class2 = class2;
}
I tried to use it through:
template<typename T, typename S>
class SubClass1 : public SuperClass<T, S> {
private:
someFunc() {
return this->_class1.getSomething(); // as an example
}
public:
SubClass1(OtherClass<T> const& class1,
OtherOtherClass<T> const& class2)
: SuperClass(class1, class2)
{
// some definitions
}
}
After that this error shows up:
member initializer
'SuperClass' does not name a non-static data member or base
class
I found some people with similar problems, but it did not lead me to the solution. For example: member initializer does not name a non-static data member or base class
I did not see many difference there and tried to add an empty constructor like he did.
The error says it all:
member initializer 'SuperClass' does not name a non-static data member or base class
SuperClass is not a class. It's a class template. As such, it's not the base class of your type. The base class is a specific instantiation of the class template: SuperClass<T,S>. That's what you need:
SubClass1(OtherClass<T> const& class1,
OtherOtherClass<T> const& class2)
: SuperClass<T,S>(class1, class2)
// ^^^^^

Parent access child private/protected

Is it possible, to somehow allow parent to access child protected members?
template <class T>
class B {
public :
void print()
{
cout << T::a << T::b << endl;
}
};
class C : public B<C>
{
protected :
static int a;
static int b;
public :
C() {
print();
}
};
This will be useful for me to inherit multiple objects without polymorphism(virtual). Any suggestgions??
Edit:
I find two solutions as suggested below ::
make the B as a friend class,
CRTP
Few more points to consider, while using CRTP make sure you use inline other wise it won't make it any faster(but code bloat may happen). Do not forget to make the B constructor protected(in case of static derived data access).
CRTP can also be used to not transfer static constant data(virtual static const) from base class to derived
The modern compilers use a concept called devirtualization i think it is in most compilers now.
This will be useful for me to inherit multiple objects without polymorphism(virtual).
It's a well known pattern and aka named static polymorphism.
The CRTP uses static_cast<T*>(this) to reference the derived class functions usually:
template <class T>
class B {
public :
void print()
{
cout << static_cast<T*>(this)->a << static_cast<T*>(this)->b << endl;
// ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
}
};
I need to somehow allow parent to access child protected data, is it possible?
Of course it is possible. These need to be public members of T, or you need to make B<T> a friend class of T:
class C : public B<C>
{
friend class B<C>;
// ^^^^^^^^^^^^^^^^^^
protected :
static int a;
static int b;
public :
C() {
print();
}
};
Live Demo
The friend declaration still preserves the encapsulation of class C, while opening access to a specific interface declared in class B<T>.

c++ template inheritance scheme

I wonder if the way I code this is correct. Can I create a template claas that inherits from a template class ? If I can, is the following code correct :
template<typename Type>
class A{
public:
A(){};
method_A(){//do whatever}
protected:
int a;
}
the second class is :
template<typename Type>
class B:public<Type> A {
public:
B(){};
method_B(){this->a=0; this->method_A();}
protected:
int b;
}
and my last class is :
class C:public<double> B{
public:
C(){};
method_C(){ b = 0; method_B();}
protected:
int c;
}
Why are the this-> mandatory in the class B but not in the class C ? And in general, should I always add this-> to reference arguments or methods that belong to the same class ?
This is specifically addressed in section 14.6.2p3 of the C++03 and C++11 standards:
In the definition of a class template or a member of a class template, if a base class of the class template depends on a template parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.

How do I forward declare a class derived from a forward declared template base class?

I am trying to forward declare a class that is derived from a template class that must also be forward declared.
Here is an example of the classes:
class TType {
public:
TType() { }
};
template<typename T>
class Base {
public:
Base() { }
};
class Derived : public Base<TType> {
public:
Derived() { }
};
Here is a failed guess at what I need:
class TType;
template<typename T> class Base;
class Derived : public Base<TType>; // This fails
Derived* pDerived;
Just forward declare the class name:
class Derived;
You can't include any more information about a class in its declaration; base classes, members, etc. can only be declared in the class definition.
This forward declaration can be used to do various things, including declaring pointers or references (such as pDerived in your example), and also declaring functions with Derived as an argument or return type. If you need to do anything that needs to know the class's size, base classes, or members, then you'll need the full definition.