modèles: parent membre de la classe des variables n'est pas visible dans la classe héritée
J'ai 4 fichiers:
arrayListType.h
: Déclarer et définirarrayListType
classe comme un modèleunorderedArrayListType.h
: Hérité dearrayListType
classe et Déclare et définitunorderedArrayListType
comme un modèle.main1.cpp
: Programme de Test pour le test deunorderedArrayListType
classe.Makefile
J'obtiens une erreur de compilation dire lors de l'accès à l'variables protégés de arrayListType
dans unorderedArrayListType
par exemple: "la longueur non déclarée dans ce cadre", "liste non déclarée dans ce cadre", où la longueur et la liste de variables protégés dans arrayListType
classe.
Voici les 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
Ce qui suit est l'erreur de compilation:
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
Plus de fonctions de unorderedArrayListType
répertoriés et protégés variables indiqués comme non déclaré dans le champ d'application. Vous vous demandez ce que pourrait être l'erreur.
Nouvelle erreur:
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'
Vous devez vous connecter pour publier un commentaire.
C'est parce que le modèle de parent d'un modèle de classe n'est pas instancié lors de la compilation passe qui examine d'abord le modèle. Ces noms apparaissent à la non-dépendant du modèle d'instanciation, et, par conséquent, les définitions doivent être disponibles. (Si vous ne regardez pas à la définition de
arrayListType
, puis la lecture du code deunorderedArrayListType
il semblerait que lelist
etlength
besoin d'être une sorte de variables globales.)Vous devez indiquer au compilateur explicitement que les noms sont en fait dépend de l'instanciation de l'objet parent.
Une façon, à l'aide de
this->
avant que tous les hérité noms:this->list
,this->length
.D'une autre manière, à l'aide de déclarations:
using arrayListType<elemType>::length;
etc (par exemple dans la partie privée de la classe dérivée).Une FAQ à ce sujet: https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
Une longue commentaire sur UncleBens réponse.
Il est toujours bon de garder à l'esprit que les modèles de classe ne sont pas des classes. Ils sont des modèles. Une façon de le regarder: En C++, les classes ne sont pas des objets. Vous devez instancier une classe pour créer un objet. Un concept similaire s'applique aux modèles de classe et des classes. Tout comme l'instanciation de classe crée un objet de la classe de l'instanciation d'un modèle crée une classe.
Jusqu'à ce que le modèle est instancié, que la relation d'héritage vous mis en place entre
unorderedArrayListType
etarrayListType
n'est pas tout à fait exister. Le compilateur ne sait pas si vous allez définir un partiel de l'instanciation d'un modèle dearrayListType
qui n'ont paslength
etlist
comme membres de données. Vous avez besoin pour donner le compilateur un coup de main dans votreunorderedArrayListType
en utilisantthis->length
etthis->list
ou une autre construction qui indique au compilateur que vous n'attendons à ce que ces données membres.Supposons que vous utilisez
this->length
dansunorderedArrayListType
, et supposons que quelqu'un écrit un partiel de l'instanciation d'un modèle dearrayListType<FooType>
qui n'ont paslength
etlist
comme membres de données. Maintenant, l'instanciation d'ununorderedArrayListType<FooType>
entraînera une erreur de compilation. Mais puisque vous n'allez pas le faire (vous n'allez pas le faire, vous?), à l'aide dethis->length
sera OK.Je voudrais essayer deux choses:
1. Utilisation
this->
(qui est généralement une bonne idée de le faire avec des modèles).2. Typedef le parent et l'utiliser lors de l'accès au parent membres: