PDA

Visualizza la versione completa : [C++] Classe (template) Array ed errori di compilazione


RooccoXXI
11-01-2011, 16:24
Ciao a tutti.
Da pochissimo mi sono dato alla programmazione tramite template e ho crecato di implementare un template di classe array molto semplice (array allocabili in fase di compilazione).

Ma il programma che ho creato mi da un sacco di errori. Probabilmente non ho capito bene come usare i template. Potreste spiegarmi dove sbaglio e perchè? Grazie.


#ifndef ARRAY_H
#define ARRAY_H

template <typename T>
class Array
{


public:
Array(int = 1); // Costruttore di default
~Array();

T &operator[](int);

private:
int dimensioneArray;
T* arrayPtr;
};

#endif

#include <iostream>
using std::cerr;

template <typename T>
Array::Array(int dimensione)
{
if (dimensione > 0) // Controlla che la dimensione sia valida
{
dimensioneArray = dimensione;
}
else // Imposta la dimensione di default (1)
{
dimensioneArray = 1;
}

arrayPtr = new T[dimensioneArray]; // Alloca l'array dinamico

for (int i = 0; i < dimensioneArray; i++) // Inizializza tutti gli elementi a 0
{
arrayPtr[i] = 0;
}
}

template <typename T>
Array::~Array()
{
delete [] arrayPtr; // Dealloca la memoria occupata
}

template <typename T>
T &Array::operator[](int elemento)
{
if (elemento < 0 or elemento > dimensioneArray)
{
cerr << "Errore: elemento inesistente." << endl;
}
}

LeleFT
11-01-2011, 17:13
Ti dà un sacco di errori: quali? Elencali.

Non puoi costringere gli utenti a copiare/incollare/testare il tuo codice... devi fornire tu tutti gli elementi necessari a trovare il problema.


Ciao. :ciauz:

RooccoXXI
11-01-2011, 19:05
Si, scusate!

Ecco gli errori!


l. 5: conflicts with previous declaration 'template<class T> class Array'
l. 26: 'template<class T> class Array' used without template parameters
ISO C++ forbids declaration of 'Array' with no type
declaration of template 'template<class T> int Array(int)'
conflicts with function declaration 'template<class T> int Array(int)'
l. 30: 'dimensioneArray' was not declared in this scope
l. 34: 'dimensioneArray' was not declared in this scope
l. 37: 'arrayPtr' was not declared in this scope
'dimensioneArray' was not declared in this scope
l. 46: expected constructor, destructor, or type conversion before '::' token
l. 52: 'template<class T> class Array' used without template parameters
'T& operator[](int)' must be a nonstatic member function

GliderKite
11-01-2011, 20:28
Tralasciando la qualità dell'implementazione:




#ifndef ARRAY_H
#define ARRAY_H


#include <iostream>


template <typename T>
class Array
{


public:
Array(int = 1); // Costruttore di default
~Array();

T & operator[](int);

private:
int dimensioneArray;
T* arrayPtr;
};



template <typename T>
Array<T>::Array(int dimensione)
{
if (dimensione > 0) // Controlla che la dimensione sia valida
{
dimensioneArray = dimensione;
}
else // Imposta la dimensione di default (1)
{
dimensioneArray = 1;
}

arrayPtr = new T[dimensioneArray]; // Alloca l'array dinamico

for (int i = 0; i < dimensioneArray; i++) // Inizializza tutti gli elementi a 0
{
arrayPtr[i] = 0;
}
}

template <typename T>
Array<T>::~Array()
{
delete [] arrayPtr; // Dealloca la memoria occupata
}

template <typename T>
T & Array<T>::operator[](int elemento)
{
if (elemento < 0 || elemento >= dimensioneArray)
{
std::cerr << "Errore: elemento inesistente." << std::endl;
}

return arrayPtr[ elemento ];
}



#endif

RooccoXXI
11-01-2011, 20:57
Originariamente inviato da GliderKite
Tralasciando la qualità dell'implementazione:

In pratica il mio errore è che utilizzavo

Array::
invece di

Array<T>::
?

RooccoXXI
11-01-2011, 21:06
Ecco la classe:


#ifndef ARRAY_H
#define ARRAY_H

#include <iostream>
using std::cerr;
using std::cout;
using std::cin;
using std::endl;

template <typename T>
class Array
{


public:
Array(int = 1); // Costruttore di default
~Array();

T &operator[](int);

void inizializza();
void visualizza() const;

private:
int dimensioneArray;
T* arrayPtr;
};

template <typename T>
Array<T>::Array(int dimensione)
{
if (dimensione > 0) // Controlla che la dimensione sia valida
{
dimensioneArray = dimensione;
}
else // Imposta la dimensione di default (1)
{
dimensioneArray = 1;
}

arrayPtr = new T[dimensioneArray]; // Alloca l'array dinamico

for (int i = 0; i < dimensioneArray; i++) // Inizializza tutti gli elementi a 0
{
arrayPtr[i] = 0;
}
}

template <typename T>
Array<T>::~Array()
{
delete [] arrayPtr; // Dealloca la memoria occupata
}

template <typename T>
T &Array<T>::operator[](int elemento)
{
if (elemento < 0 or elemento > dimensioneArray)
{
cerr << "Errore: elemento inesistente." << endl;
}
}

template<typename T>
void Array<T>::inizializza()
{
for (int i = 0; i < dimensioneArray; i++)
{
cout << "array[" << i << "]: ";
cin >> arrayPtr[i];
}
}

template<typename T>
void Array<T>::visualizza() const
{
for (int i = 0; i < dimensioneArray; i++)
{
cout << "array[" << i << "] = " << arrayPtr[i] << endl;
}
}

#endif

Grazie mille per l'help!

Comunque è già un miglioramento degli array normali o è una classe inutile? (So che mancano le ridefinizioni degli operatori, il costruttore di copia, ..., ma volevo farla semplice semplice!).

MItaly
11-01-2011, 21:28
Di sicuro in un container "vero" non mescolerai mai il codice della classe-container con quello di interfaccia con l'utente. Gli errori non si riportano scrivendo sullo schermo, ma con le eccezioni.

RooccoXXI
11-01-2011, 21:36
Originariamente inviato da MItaly
Di sicuro in un container "vero" non mescolerai mai il codice della classe-container con quello di interfaccia con l'utente. Gli errori non si riportano scrivendo sullo schermo, ma con le eccezioni.

So che non si dovrebbe fare. Però visto il mio livello di programmazione (sicuramente non metterò mai in vendita una classe!xD) e che i template devono comunque essere specificati su un file .h li ho messi assieme.

Comunque mi hai ricordato che è meglio utilizzare la gestione delle eccezioni per l'operatore new (bad_alloc). Mentre se il valore immesso dall'utente esce dall'array come faccio autilizzare la gestione delle eccezioni? Si possono creare eccezioni ad hoc?!

MItaly
11-01-2011, 21:40
Originariamente inviato da RooccoXXI
Mentre se il valore immesso dall'utente esce dall'array come faccio autilizzare la gestione delle eccezioni? Si possono creare eccezioni ad hoc?!
Puoi usare l'eccezione std::out_of_range definita in <stdexcept>; puoi comunque creare delle tue eccezioni, possibilmente derivando da std::exception (definita in <exception>).

RooccoXXI
11-01-2011, 22:46
Originariamente inviato da MItaly
Puoi usare l'eccezione std::out_of_range definita in <stdexcept>; puoi comunque creare delle tue eccezioni, possibilmente derivando da std::exception (definita in <exception>).

Troppo complesso per il mio livello, ma buono a sapersi! =).

Loading