2

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 ?

PinkFloyd
  • 2,103
  • 4
  • 28
  • 47
  • 4
    Did you mean `A` and `B`? – jrok Jul 21 '13 at 13:55
  • It's actually called a *class template*, not a *template class*. This is a hint that once you instantiate a class template, it's no longer a template, but just a class. – dyp Jul 21 '13 at 13:56
  • Note you cannot access `private` members defined in base classes from derived classes. Make it either `protected` or use getter/setter functions. – dyp Jul 21 '13 at 13:57
  • 2
    related: http://stackoverflow.com/q/6592512/951890 – Vaughn Cato Jul 21 '13 at 13:58
  • The reason `this->` is mandatory in B is that it is a template and `a` and `method_A` are *dependent names*. See [here](http://stackoverflow.com/questions/1120833/derived-template-class-access-to-base-class-member-data) for example. `B`, however, is a specialization of B, a concrete class. – jrok Jul 21 '13 at 13:59
  • @jrok I'd rather say the problem is that the *base class name* is dependent, see [temp.dep]/3. The names of the members are **not found** via name lookup. – dyp Jul 21 '13 at 14:04
  • @Dyp : sure, it's protected that i meant! – PinkFloyd Jul 21 '13 at 14:08
  • @jro: thanks for the link ! which is then better : `this->method_a()` or `A::method_a()`? – PinkFloyd Jul 21 '13 at 14:14
  • 1
    substituting `method_a()` with `this->method_a()` is the most direct way to address this issue. If you use `A::method_a()` then you are saying something slightly different, since `A::method_a()` will not perform dynamic binding in the case that `method_a()` is a virtual function. – Vaughn Cato Jul 21 '13 at 22:46
  • @VaughnCato Does it change anything if the classes A and B are pure virtual and creating a C will actually provide a type ? – PinkFloyd Jul 22 '13 at 11:56
  • @PinkFloyd: no, although if `method_a` is being overridden in class `C`, then calling `method_a` won't be an issue, since `method_a`'s declaration will be visible. – Vaughn Cato Jul 22 '13 at 13:40

1 Answers1

3

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.

Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132