Простой шаблон наследования C ++ - PullRequest
5 голосов
/ 10 февраля 2011
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;
}

Показан мой базовый класс, одна переменная защищенного члена, один установщик

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
}

Теперь это мой подкласс первого.По какой-то причине прямой доступ к защищенной переменной-члену не работает, хотя я считаю, что это необходимоОднако доступ к сеттеру работает нормально.Я нуб с C ++, я уверен, что упускаю что-то очевидное.

1 Ответ

8 голосов
/ 10 февраля 2011

Причиной того, что это не работает, является странность способа, которым шаблоны 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, и помогает компилятору узнать, что выговорить о.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...