Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [C++]problema con template

    Ho la seguente classe:
    codice:
     
    //////////////////////////////////////////////////////////////////////
    // Vettore.h: interface for the Vettore class.
    //
    //////////////////////////////////////////////////////////////////////
    #define DIM_STANDARD 10
    
    template<class T>
    class Vettore  
    {
    public:
    	///////////////////////////////
        // Costruttori/distruttori
        ///////////////////////////////
    	Vettore();
    	Vettore(int dim);
    	virtual ~Vettore();	
    	///////////////////////////////
        // Utilita di ricerca
        ///////////////////////////////
    	void Ordina();
    	int cerca(int size, T a[], T key);
    	///////////////////////////////
        // Funzioni di interfaccia
        ///////////////////////////////
    	int getDimensione();
    	T getElemento(int pos);
    	///////////////////////////////
        // Funzioni vettore
        ///////////////////////////////
    	void AggiungiElemento(T elemento, int pos);
    	void AggiungiElemento(T elemento);
    	void RimuoviElemento(int pos);
    
    private:
    	T* elementi; // gli elementi
    	int dimensione; // la dimensione
    
    };
    Implementata cosi:
    codice:
     //////////////////////////////////////////////////////////////////////
    // Vettore.cpp: implementation of the Vettore class.
    //
    //////////////////////////////////////////////////////////////////////
    #include "Vettore.h"
    
    //////////////////////////////////////////////////////////////////////
    // Construttore a un argomento
    //////////////////////////////////////////////////////////////////////
    template<class T>
    Vettore<T>::Vettore(int dim)
    {
    	dimensione = (dim < 0) ? DIM_STANDARD : dim;
    	elementi[dim] = new T[dim];
    	for(int i=0;i<dimensione;i++)
    	{
    		dimensione[i] = NULL;
    	}
    
    }
    
    //////////////////////////////////////////////////////////////////////
    // Construttore standard
    //////////////////////////////////////////////////////////////////////
    template<class T>
    Vettore<T>::Vettore()
    {
    	elementi[DIM_STANDARD] = new T[DIM_STANDARD];
    	dimenione = MAX;
    	for(int i=0;i<dimensione;i++)
    	{
    		dimensione[i] = NULL;
    	}
    }
    
    //////////////////////////////////////////////////////////////////////
    // Distruttore standard
    //////////////////////////////////////////////////////////////////////
    template<class T>
    Vettore<T>::~Vettore()
    {
    	delete[] elementi;
    }
    
    //////////////////////////////////////////////////////////////////////
    // Restituisce la dimensione
    //////////////////////////////////////////////////////////////////////
    template<class T>
    int Vettore<T>::getDimensione()
    {
    	return dimensione;
    }
    //////////////////////////////////////////////////////////////////////
    // Ordina gli elementi
    //////////////////////////////////////////////////////////////////////
    template<class T>
    void Vettore<T>::Ordina()
    {
    	bool is_sorted=false;
    	int p=0,q=0;
    	T tmp;// la variabile temporanea di appoggio
    
    	while(!is_sorted){
    		is_sorted=true;
    		++p;// p viene avanzato e poi visualizzato
    		for(q=0;q<size-p;++q){
    			if(elementi[q]>a[q+1]){
    			tmp=elementi[q];
    			elementi[q]=elementi[q+1];
    			elementi[q+1]=tmp;
    			is_sorted=false;// esce dal for
    			}
    		}
    	}
    }
    //////////////////////////////////////////////////////////////////////
    // Reicerca elementi
    //////////////////////////////////////////////////////////////////////
    template<class T>
    int Vettore<T>::cerca(int size, T a[], T key)
    {
    	for(int i=0;i<size;i++)
    	{
    		if(a[i] == key)
    			return i;
    	}
    
    	return -1;
    }
    //////////////////////////////////////////////////////////////////////
    // Aggiunge un elemento (con posizione specificata)
    //////////////////////////////////////////////////////////////////////
    template<class T>
    void Vettore<T>::AggiungiElemento(T elemento, int pos)
    {
    	if( (pos <= dimensione) && (pos > 0) )
    		elementi[pos] = elemento;
    }
    
    //////////////////////////////////////////////////////////////////////
    // Aggiunge un elemento (senza posizione specificata)
    //////////////////////////////////////////////////////////////////////
    template<class T>
    void Vettore<T>::AggiungiElemento(T elemento)
    {
    	for(int pass=0;pass<dimensione;pass++)
    	{
    		if(elementi[pass] == NULL)
    			elementi[pass] = elemento
    		break; // esce dal for
    	}
    }
    //////////////////////////////////////////////////////////////////////
    // Restituisce un elemento (posizione specificata)
    //////////////////////////////////////////////////////////////////////
    template<class T>
    T Vettore<T>::getElemento(int pos)
    {
    	return elementi[pos];
    }
    //////////////////////////////////////////////////////////////////////
    // Rimuove un elemento (con posizione specificata)
    //////////////////////////////////////////////////////////////////////
    template<class T>
    void Vettore<T>::RimuoviElemento(int pos)
    {
    	if( (pos <= dimensione) && (pos > 0) )
    	elementi[pos] = NULL;
    }
    E ho questo test:
    codice:
     // test.cpp
    #include <iostream>
    #include "Vettore.h"
    
    using namespace std;
    
    int main()
    {
    	Vettore<int> vet(5);
    	vet.AggiungiElemento(3, 1);
    	vet.AggiungiElemento(5);
    	vet.Ordina();
    	for(int i;i<vet.getDimensione();i++)
    	{
    		cout << "Vettore " << i << ": " << vet.getElemento(i)<<endl;
    	}
    	return 0;
    }
    Ma mi da:
    Test.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall Vettore<int>::~Vettore<int>(void)" (??1?$Vettore@H@@UAE@XZ)
    Test.obj : error LNK2001: unresolved external symbol "public: int __thiscall Vettore<int>::getElemento(int)" (?getElemento@?$Vettore@H@@QAEHH@Z)
    Test.obj : error LNK2001: unresolved external symbol "public: int __thiscall Vettore<int>::getDimensione(void)" (?getDimensione@?$Vettore@H@@QAEHXZ)
    Test.obj : error LNK2001: unresolved external symbol "public: void __thiscall Vettore<int>::Ordina(void)" (?Ordina@?$Vettore@H@@QAEXXZ)
    Test.obj : error LNK2001: unresolved external symbol "public: void __thiscall Vettore<int>::AggiungiElemento(int)" (?AggiungiElemento@?$Vettore@H@@QAEXH@Z)
    Test.obj : error LNK2001: unresolved external symbol "public: void __thiscall Vettore<int>::AggiungiElemento(int,int)" (?AggiungiElemento@?$Vettore@H@@QAEXHH@Z)
    Test.obj : error LNK2001: unresolved external symbol "public: __thiscall Vettore<int>::Vettore<int>(int)" (??0?$Vettore@H@@QAE@H@Z)
    Debug/Vettore.exe : fatal error LNK1120: 7 unresolved externals
    Error executing link.exe.
    La stupidità umana e l'universo sono infinite.
    Della seconda non sono certo(Einstein)

    Gnu/Linux User

  2. #2
    Di classi e funzioni template devi scrivere tutto il codice dentro l`header, sia dichiarazioni che definizioni. Per il resto ci sono svariati errori:

    1)

    codice:
    elementi[dim] = new T[dim];
    	for(int i=0;i<dimensione;i++)
    	{
    		dimensione[i] = NULL;
    	}
    Diventa:

    codice:
    elementi = new T[ dim ];
    
    // e nient`altro, tanto si affida al costruttore di default
    Stesso discorso per Vettore().

    2) Posto cosi`, cerca() andrebbe reso static perche` non si fa minimo cenno all`oggetto chiamante, e forse non e` quello che intendevi fare. Quindi:

    codice:
    int Vettore<T>::cerca(int size, T a[], T key)
    {
    	for(int i=0;i<size;i++)
    	{
    		if(a[i] == key)
    			return i;
    	}
    
    	return -1;
    }
    Diventa:

    codice:
    int Vettore< T >::cerca( T key )
    {
    	for( int i = 0; i < dimensione; ++i )
    	{
    		if( elementi[ i ] == key )
    			return i;
    	}
    
    	return -1;
    }
    3) I metodi AggiungiElemento()/RimuoviElemento() li vedo un po` "bizzarri".. Inoltre questa condizione e` errata:

    codice:
    (pos <= dimensione) && (pos > 0)
    Piuttosto:

    codice:
    (pos < dimensione) && (pos >= 0)
    Per l`accesso agli elementi usa il piu` intuitivo operator[].

    l-value:

    codice:
    template< class T >
    T& Vettore< T >::operator[]( size_t pos )
    {
    	return elementi[ pos ];
    }
    r-value:

    codice:
    template< class T >
    const T& Vettore< T >::operator[]( size_t pos ) const
    {
    	return elementi[ pos ];
    }
    Ciao.

  3. #3
    Utente di HTML.it L'avatar di Zalex
    Registrato dal
    Aug 2001
    Messaggi
    357
    Originariamente inviato da r0x
    Di classi e funzioni template devi scrivere tutto il codice dentro l`header, sia dichiarazioni che definizioni.
    Questo non e' sempre vero!dipende dal compilatore........cmq e' sempre meglio mettere tutto nell'header!


    per quando riguarda il codice di luc@s, contiene un po' di errori......
    a parte un punto e virgola mancante
    ..........
    if(elementi[pass] == NULL)
    elementi[pass] = elemento;
    break; // esce dal for
    ...........
    e una inizializzazione credo dimenticata(nel main)
    for(int i=0;i<vet.getDimensione();i++)
    {
    cout << "Vettore " << i << ": " << vet.getElemento(i)<<endl;
    }
    che puo capitare ,
    te ne elenco alcuni:
    Nel costruttore a un argomento
    -elementi[dim] = new T[dim]; la new ritorna un puntatore,in questo caso un int * che non puoi assegnare a un int

    -for(int i=0;i<dimensione;i++)
    {
    dimensione[i] = NULL;
    }
    dimensione ha tipo int!come fai a usare il subscripting??non e' un array!

    -nel metodo Ordina(): 'size' da dove salta fuori?e la 'a'?

    -nel metodo AggiungiElemento c'e' un controllo un po strano...(secondo me):master:
    if(elementi[pass] == NULL)non e' un confronto tra puntatori!e NULL lo vedrei piu in un confronto tra puntatori

    per quanto riguarda il metodo cerca,ritengo che non abbia senso l'implementazione da te fornita per un semplice motivo : perche' passare per valore l'array in cui cercare?allora a cosa serve la classe,l'oggetto di invocazione,ecc?non avrebbe nemmeno senso falo static perche' non e' un metodo inerente alla classe!cioe' ci potrebbero essere contemporaneamente piu' istanze della stessa classe e una ricerca statica dove cerca?la nuova implementazione di r0x mi sembra piu sensata.

    bhe credo che correggendo questi (piccoli?) errori e rivedendo meglio il metodo Ordina possa funzionare abbastanza bene.....anche se in questi casi preferisco usare le liste,ma questo e' solo un punto di vista
    ciao

  4. #4
    codice:
    Questo non e' sempre vero!dipende dal compilatore........cmq e' sempre meglio mettere tutto nell'header!
    In un modo o nell`altro, l`importante e` che il corpo della classe/funzione template che si intende utilizzare in un sorgente sia visibile. Poi certo la procedura e` specifica del compilatore. Cmq se metti la definizione nell`header vai tranquillo e ti eviti noie non indifferenti.

    Per lo static: sintatticamente altroche` se ha senso, effettua la ricerca nell`array passato come parametro. E` naturalmente _ovvio_ che un metodo del genere non serve a un ca**o.

  5. #5
    risolto!
    La stupidità umana e l'universo sono infinite.
    Della seconda non sono certo(Einstein)

    Gnu/Linux User

  6. #6
    Per Zalex: certo che e' sempre vero, ovvero secondo quello che dice l'ISO C++. Se vuoi dividere la definizione dalla dichiarazione devi usare la parola chiave export da applicare alla dichiarazione.

    Bye
    There are 10 kinds of people in the world: who knows the binary numeration and who not

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.