Vorlagen: Elternklassen-Membervariablen, die in der geerbten Klasse nicht sichtbar sind
Habe ich folgende 4 Dateien:
arrayListType.h
: Deklarieren und definierenarrayListType
Klasse als VorlageunorderedArrayListType.h
: Geerbt vonarrayListType
Klasse und Erklärt und definiertunorderedArrayListType
als Vorlage.main1.cpp
: Test-Programm zum testenunorderedArrayListType
Klasse.Makefile
Bekomme ich einen compile-Fehlermeldung beim Zugriff auf die protected-Variablen der arrayListType
im unorderedArrayListType
zum Beispiel: "Länge nicht deklariert, in diesem Umfang", "Liste nicht deklariert, in diesem Umfang", wobei Länge und Liste der geschützten Variablen im arrayListType
Klasse.
Im folgenden sind die codes:
arrayListType.h
#ifndef H_arrayListType
#define H_arrayListType
#include <iostream>
using namespace std;
template <class elemType>
class arrayListType
{
public:
const arrayListType<elemType>&operator=(const arrayListType<elemType>&);
bool isEmpty() const;
bool isFull() const;
int listSize() const;
int maxListSize() const;
void print() const;
bool isItemAtEqual(int location, const elemType& item) const;
virtual void insertAt(int location, const elemType& insertItem) = 0;
virtual void insertEnd(const elemType& insertItem) = 0;
void removeAt(int location);
void retrieveAt(int location, elemType& retItem) const;
virtual void replaceAt(int location, const elemType& repItem) = 0;
void clearList();
virtual int seqSearch(const elemType& searchItem) const;
virtual void remove(const elemType& removeItem) = 0;
arrayListType(int size = 100);
arrayListType(const arrayListType<elemType>& otherList);
virtual ~arrayListType();
protected:
elemType *list;
int length;
int maxSize;
};
template <class elemType>
bool arrayListType<elemType>::isEmpty() const
{
return (length == 0);
}
//remaining non-virtual functions of arrayListType class
#endif
unorderedArrayListType.h
#ifndef H_unorderedArrayListType
#define H_unorderedArrayListType
//#include <iostream>
#include "arrayListType.h"
//using namespace std;
template <class elemType>
class unorderedArrayListType: public arrayListType<elemType>
{
public:
void insertAt(int location, const elemType& insertItem);
void insertEnd(const elemType& insertItem);
void replaceAt(int location, const elemType& repItem);
int seqSearch(const elemType& searchItem) const;
void remove(const elemType& removeItem);
unorderedArrayListType(int size = 100);
};
template <class elemType>
void unorderedArrayListType<elemType>::insertAt(int location, const elemType& insertItem)
{
for(int i = length; i > location; i--)
list[i] = list[i - 1];
list[location] = insertItem;
length++;
}
//Remaining virtual functions that need to be defined by the inherited class
#endif
main1.cpp
#include <iostream>
#include "unorderedArrayListType.h"
using namespace std;
int main()
{
unorderedArrayListType<int> intList(25);
int number;
cout<<"Line 3: Enter 8 integers: ";
for(int count = 0; count < 8; count++)
{
cin>>number;
intList.insertEnd(number);
}
cout<<"Line 8: intList: ";
intList.print();
cout<<endl;
}
Makefile:
all: main1
main1.o: main1.cpp
g++ -c -Wall main1.cpp
main1: main1.o
g++ -Wall main1.o -o main
clean:
rm -f *.o *~ main1
Folgenden ist die Zusammenstellung Fehler:
make
g++ -c -Wall main1.cpp
In file included from main1.cpp:2:
unorderedArrayListType.h: In member function 'void unorderedArrayListType<elemType>::insertAt(int, const elemType&)':
unorderedArrayListType.h:30: error: 'length' was not declared in this scope
unorderedArrayListType.h:31: error: 'list' was not declared in this scope
unorderedArrayListType.h:33: error: 'list' was not declared in this scope
Mehr Funktionen unorderedArrayListType
aufgeführt und geschützte Variablen angegeben, als nicht deklariert in den Rahmen. Frage mich, was könnte der Fehler.
Neuen Fehler:
make
g++ -Wall main1.o -o main
Undefined first referenced
symbol in file
arrayListType<int>::seqSearch(int const&) constmain1.o
ld: fatal: Symbol referencing errors. No output written to main
collect2: ld returned 1 exit status
*** Error code 1
make: Fatal error: Command failed for target `main1'
Kommentar zu dem Problem
möglich, Duplikat der Warum habe ich Zugriff auf template-Basis-Klasse-Mitglieder durch den this-Zeiger?
InformationsquelleAutor der Frage Romonov | 2011-07-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist, weil die Vorlage übergeordnete Vorlage-Klasse wird nicht instanziiert, während die Zusammenstellung übergeben, die untersucht zunächst die Vorlage. Diese Namen erscheinen nicht-abhängig von der jeweiligen template-Instantiierung, und daher die Definitionen zur Verfügung stehen müssen. (Wenn Sie schauen nie auf die definition von
arrayListType
, dann Lesen Sie den code vonunorderedArrayListType
es scheint, dielist
undlength
brauchen, um irgendeine Art von globals.)Müssen Sie dem compiler explizit, dass die Namen sind in der Tat abhängig von der Instanziierung der Eltern.
Einen Weg, mit
this->
vor allem die ererbten Namen:this->list
,this->length
.Einen anderen Weg, mit Erklärungen:
using arrayListType<elemType>::length;
etc (z.B. in den private-Abschnitt der abgeleiteten Klasse).Einen FAQ-Eintrag dazu: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.19
InformationsquelleAutor der Antwort UncleBens
Einen längeren Kommentar auf UncleBens " Antwort.
Ist es immer gut im Auge zu behalten, dass Klassen-templates sind nicht Klassen. Sie sind Vorlagen. Eine Möglichkeit es zu betrachten: In C++ sind die Klassen keine Objekte. Sie müssen zum instanziieren einer Klasse ein Objekt zu erstellen. Ein ähnliches Konzept gilt auch für Klassen-templates und-Klassen. Genauso Klasse Instanziierung erzeugt ein Objekt der Klasse template-Instantiierung erzeugt eine Klasse.
Bis das template instanziiert wird, wird die Vererbung von der Beziehung zwischen
unorderedArrayListType
undarrayListType
nicht ganz vorhanden ist. Der compiler weiß nicht, ob Sie gehen, um definieren eine partielle template-Instantiierung vonarrayListType
dass nichtlength
undlist
als Daten-member. Müssen Sie dem compiler eine hand in IhrenunorderedArrayListType
mithilfethis->length
undthis->list
oder einige andere konstruieren, teilt dem compiler mit, dass Sie erwarten, dass diese Daten von Mitgliedern.Angenommen, Sie verwenden
this->length
imunorderedArrayListType
, und annehmen, dass jemand kommt und schreibt eine partielle template-Instantiierung vonarrayListType<FooType>
dass nichtlength
undlist
als Daten-member. Jetzt die Instanziierung einerunorderedArrayListType<FooType>
Ergebnis der Kompilierung Fehler. Aber da Sie nicht gehen, um zu tun (Sie nicht gehen zu tun, oder?), mitthis->length
OK sein.InformationsquelleAutor der Antwort David Hammen
Ich würde versuchen, zwei Dinge:
1. Verwenden
this->
(das ist generell eine gute Idee zu tun, mit Vorlagen).2. Typedef die Eltern und verwenden Sie es, wenn der Zugriff auf die übergeordneten Elemente:
InformationsquelleAutor der Antwort selalerer