简单的模板继承问题C++

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++的菜鸟,我敢肯定我错过了一些明显的东西.

tem*_*def 8

这不起作用的原因是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来源明确无误,并帮助编译器知道你在说什么.

希望这可以帮助!