Re: Inheritance from a Template class, problems accessing protected
member
liam_herron wrote:
Here is my code:
#include <iostream>
template<typename T>
class RawPtr
{
protected:
T* pointee_;
public:
RawPtr() : pointee_(0) {}
RawPtr(T* pT) : pointee_(pT) {}
};
template<typename T>
class SmartPtr : public RawPtr<T>
when the compiler gets here, it will encounter a name `RawPtr<T>', and
knows that that is a template class of type<T>. when a class is
inherited from a template class, compiler will *only* find the template
base class *name* in his symbol table, and will not check its definition
detail.
{
public:
SmartPtr() : RawPtr<T>() {}
explicit SmartPtr(T* pT) : RawPtr<T>(pT)
{
if (pointee_ != 0)
The reason of your original code is the template specialization. when
you're defining your SmartPtr<T> here, compiler only know his base
template class name but not his details, so compiler doesn't know
SmartPtr<T> has a member pointee_ inherited from RawPtr<T>. But you
could explicitly point that out using:
if(this->pointee_ != 0)
or
if(RawPtr<T>::pointee_ != 0)
this will tell the compiler that there is a implicit rule that RawPtr<T>
has to contain a member named pointee_, and this rule will be checked
when you instantiate a SmartPtr<T> object.
{
std::cout << "SmartPtr(T* pT): pointee_ non-null." <<
std::endl;
}
}
};
int main()
{
double *pDoubleRaw = new double(1.0);
SmartPtr<double> pDouble(pDoubleRaw);
return 0;
}
On Linux (g++ (GCC) 3.4.6 20060404 (Red Hat 3.4.6-3)) I get the
following compilation error:
g++ testInheritanceWithTemplates.cpp
testInheritanceWithTemplates.cpp: In constructor
`SmartPtr<T>::SmartPtr(T*)':
testInheritanceWithTemplates.cpp:27: error: `pointee_' was not
declared in this scope
On Windows, this compiles fine.
Any ideas why this doesn't work on Linux? Does the C++ standard think
that this is legal?
Regards,
Liam Herron
what g++ has done here is right. because of template specialization,
compiler will not guarantee anything at complier time. think about this:
template<typename T> class base;
template<> class base<int>
{
protected:
int i;
};
template<> class base<double>
{
protected:
double foo()
{
return .0;
}
};
template<typename T>
class derived : public base<T>
{
int bar()
{
//i; is there `i'?
//foo(); or is there a foo()?
return 0;
}
};
in derived<T>::bar(), what should the compiler guarantee you? a `i' or
`foo()', or even something else? -- nothing is good, so just guarantee
nothing here. you should cry for what you want exactly and compiler will
check it for you when it instantiates that.
cheers & HTH,
Jim