szablony:zmienne składowe klasy nadrzędnej nie są widoczne w klasie dziedziczonej

szablony:zmienne składowe klasy nadrzędnej nie są widoczne w klasie dziedziczonej

Dzieje się tak, ponieważ element nadrzędny szablonu klasy szablonu nie jest tworzony podczas przebiegu kompilacji, który najpierw bada szablon. Nazwy te wydają się być niezależne od konkretnej instancji szablonu, dlatego muszą być dostępne definicje. (Jeśli nigdy nie spojrzysz na definicję arrayListType , a następnie odczytanie kodu unorderedArrayListType wyglądałoby to na list i length muszą być czymś w rodzaju globalnych).

Musisz wyraźnie powiedzieć kompilatorowi, że nazwy są w rzeczywistości zależne od instancji rodzica.

W jedną stronę, używając this-> przed wszystkimi odziedziczonymi nazwami:this->list , this->length .

Inny sposób, używając deklaracji:using arrayListType<elemType>::length; itp. (na przykład w prywatnej sekcji klasy pochodnej).

Wpis FAQ na ten temat:https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members


Rozszerzony komentarz do odpowiedzi wujka.

Zawsze dobrze jest pamiętać, że szablony klas nie są klasami. To są szablony. Jeden ze sposobów patrzenia na to:w C++ klasy nie są obiektami. Aby utworzyć obiekt, musisz utworzyć instancję klasy. Podobna koncepcja dotyczy szablonów i klas klas. Tak jak instancja klasy tworzy obiekt, instancja szablonu klasy tworzy klasę.

Dopóki szablon nie zostanie utworzony, ta relacja dziedziczenia, którą utworzyłeś między unorderedArrayListType i arrayListType nie całkiem istnieje. Kompilator nie wie, czy zamierzasz zdefiniować częściową instancję szablonu arrayListType który nie ma length i list jako członkowie danych. Musisz pomóc kompilatorowi w swoim unorderedArrayListType za pomocą this->length i this->list lub jakaś inna konstrukcja, która mówi kompilatorowi, że oczekujesz, że będą to składowe danych.

Załóżmy, że używasz this->length w unorderedArrayListType i załóżmy, że ktoś przychodzi i pisze częściową instancję szablonu arrayListType<FooType> który nie ma length i list jako członkowie danych. Teraz tworzę instancję unorderedArrayListType<FooType> spowoduje błąd czasu kompilacji. Ale ponieważ nie zamierzasz tego zrobić (nie zamierzasz tego zrobić, prawda?), używając this->length będzie OK.


Spróbowałbym dwóch rzeczy:

1. Użyj this-> (co jest ogólnie dobrym pomysłem w przypadku szablonów).

template <class elemType>
void unorderedArrayListType<elemType>::insertAt(int location, const elemType& insertItem)
{
    for(int i = this->length; i > location; i--)
        this->list[i] = this->list[i - 1];

    this->list[location] = insertItem;
    this->length++;
}

2. Wpisz definicję rodzica i użyj go podczas uzyskiwania dostępu do członków rodzica:

template <class elemType>
class unorderedArrayListType: public arrayListType<elemType>
{
    typedef arrayListType<elemType> Parent;
    ...
}

template <class elemType>
void unorderedArrayListType<elemType>::insertAt(int location, const elemType& insertItem)
{
    for(int i = Parent::length; i > location; i--)
        Parent::list[i] = Parent::list[i - 1];

    Parent::list[location] = insertItem;
    Parent::length++;
}