2011-02-10 89 views
5
template <class T> 
class baseclass{ 
protected: 
    T data; 
public: 
    baseclass(){}; 
    void setData(T d); 
}; 

template<class T> 
void baseclass<T>::setT(T d){ 
    data = d; 
} 

上面显示的是我的基类,一个受保护的成员变量,一个setter。简单模板继承问题C++

template <class T> 
class aclass : public baseclass<T> 
{ 
    public: 
     aclass(T d); 
}; 

template<class T> 
aclass<T>::aclass(T d){ 
    setData(d); <---WORKS 
    data = d; <---DOESN'T WORK 
} 

现在这是我的第一个子类。出于某种原因,直接访问受保护的成员变量不起作用,尽管我相信它应该。但是,访问setter工作正常。我是C++的noob,我确定我错过了一些明显的东西。

+0

如果你写这个 - > data = d ;? – 2011-02-10 06:28:01

+0

您能否更具体地表示“不起作用”?你是否得到了一个编译器错误(如果是这样,哪一个),或者它在运行时什么都不做? – 2011-02-10 06:30:38

回答

8

的原因,这并不工作在C++模板名称解析的方式怪癖。特别是,如果您有一个模板类继承自另一个依赖于模板类型的类(就像您在这种情况下做的那样),您无法直接访问该基类的成员,而无需向编译器提供关于何处的提示看。这是你得到错误的原因。

为了解决这个问题,你可以重写你的构造函数

template<class T> 
aclass<T>::aclass(T d){ 
    setData(d); 
    this->data = d; 
} 

现在,编译器知道data必须以某种方式的aclass<T>一员,它可以找到它的寻找。

有趣的是,你也应该因为同样的原因在上一行出现错误。我不确定它为什么决定编译。为了解决这个问题,你可以这样做:

template<class T> 
aclass<T>::aclass(T d){ 
    this->setData(d); 
    this->data = d; 
} 

或者,你可以添加一个using声明告诉aclass继承其父类setData方法的编译程序。在类的声明,可以考虑加入这一行:

template <class T> 
class aclass : public baseclass<T> 
{ 
    public: 
     aclass(T d); 

     using baseclass<T>::setData; 
}; 

this->数据成员,这一招使得它毫不含糊其中名称setData来自和帮助编译器知道你在说什么。

希望这会有所帮助!