jak*_*kev 5 c++ inheritance templates
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;
}
Run Code Online (Sandbox Code Playgroud)
上面显示的是我的基类,一个受保护的成员变量,一个setter.
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
}
Run Code Online (Sandbox Code Playgroud)
现在这是我的第一个子类.出于某种原因,直接访问受保护的成员变量是不行的,虽然我认为它应该.但是,访问setter工作正常.我是C++的菜鸟,我敢肯定我错过了一些明显的东西.
这不起作用的原因是C++模板命名解析方式的怪癖.特别是,如果你有一个从依赖于一个模板类型(如你在这种情况下做的)另一个类继承的模板类,你不能直接不给编译器在哪里暗示访问基类成员看.这是你得到的错误的原因.
要解决此问题,您可以将构造函数重写为
template<class T>
aclass<T>::aclass(T d){
setData(d);
this->data = d;
}
Run Code Online (Sandbox Code Playgroud)
现在编译器知道data必须以某种方式成为其成员aclass<T>,它可以找到它正在寻找的东西.
有趣的是,出于同样的原因,您还应该在上一行中收到错误.我不确定为什么决定编译.要解决此问题,您可以执行以下操作:
template<class T>
aclass<T>::aclass(T d){
this->setData(d);
this->data = d;
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以添加一个using声明来告诉编译器从其父类aclass继承该setData方法.在类声明中,考虑添加以下行:
template <class T>
class aclass : public baseclass<T>
{
public:
aclass(T d);
using baseclass<T>::setData;
};
Run Code Online (Sandbox Code Playgroud)
与this->for data成员一样,这个技巧使得名称的setData来源明确无误,并帮助编译器知道你在说什么.
希望这可以帮助!