I am trying to access base-class data in my C++ code without using the "this" pointer. My classes are templated, and ClassA
is the base class for ClassB
, which is the base class for ClassC
. All classes are publicly derived from their base classes. I found this discussion which gets me half-way to a solution, but doesn't resolve it completely:
Why do I have to access template base class members through the this pointer?
That page suggests I should be able to fix my problem with the "using" statement. Here is an example of what I am trying to do:
#include <iostream>
template <typename FP>
class ClassA
{
protected:
FP a ;
} ;
template <typename FP>
class ClassB : public ClassA <FP>
{
using ClassA <FP> :: a ;
public:
void fooB ( void ) { std:: cout << a << std::endl ; }
} ;
template <typename FP>
class ClassC : public ClassB <FP>
{
using ClassA <FP> :: a ;
public:
void fooC ( void ) { std:: cout << a << std::endl ; }
} ;
int main ( int argc, char *argv[] )
{
ClassB <double> tempB ;
ClassC <double> tempC ;
tempB.fooB ( ) ;
tempC.fooC ( ) ;
return 0 ;
}
The code above fails to compile, giving the error below:
stepTWO.cpp: In instantiation of ‘class ClassC<double>’:
stepTWO.cpp:30:25: required from here
stepTWO.cpp:8:12: error: ‘double ClassA<double>::a’ is protected
FP a ;
^
stepTWO.cpp:20:11: error: within this context
class ClassC : public ClassB <FP>
What I've found is that "using" will make the variable accessible in either ClassB
or ClassC
, but not both. If I put the using statement in both classes, I get the error shown above. All inheritance is done through public derivation.
Does anyone know of a solution to make this work? (Other than using "this" or fully-qualified scope names to access my data elements?)
Your problem here is that in ClassB
the using ClassA <FP> :: a ;
is in the private section of the class. That means a derived class will not be able to access it. What you need to do is put it in a protected section like the variable is declared ClassA
. Doing that you get:
#include <iostream>
template <typename FP>
class ClassA
{
protected:
FP a ;
} ;
template <typename FP>
class ClassB : public ClassA <FP>
{
protected:
using ClassA <FP> :: a ; // protected so it can be inherited
public:
void fooB ( void ) { std:: cout << a << std::endl ; }
} ;
template <typename FP>
class ClassC : public ClassB <FP>
{
using ClassA <FP> :: a ;
public:
void fooC ( void ) { std:: cout << a << std::endl ; }
} ;
int main ( int argc, char *argv[] )
{
ClassB <double> tempB ;
ClassC <double> tempC ;
tempB.fooB ( ) ;
tempC.fooC ( ) ;
return 0 ;
}