当前位置 : 主页 > 手机开发 > 其它 >

简单的模板继承问题C.

来源:互联网 收集:自由互联 发布时间:2021-06-19
template class Tclass baseclass{protected: T data;public: baseclass(){}; void setData(T d);};templateclass Tvoid baseclassT::setT(T d){ data = d;} 上面显示的是我的基类,一个受保护的成员变量,一个setter. template class Tc
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.

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

这不起作用的原因是C模板命名解析方式的怪癖.特别是,如果你有一个继承自另一个依赖于模板类型的类的模板类(正如你在这种情况下所做的那样),你不能直接访问该基类的成员而不给编译器一个提示看.这是你得到的错误的原因.

要解决此问题,您可以将构造函数重写为

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

现在编译器知道数据必须以某种方式成为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;
};

喜欢这个 – >对于数据成员来说,这个技巧使得名称setData的来源明确无误,并帮助编译器知道你在说什么.

希望这可以帮助!

网友评论