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

    [C++] Riconoscimento tipi scalari

    Devo implementare una mia classe vector. In questa classe è presente un metodo clear() che si occupa di eliminare gli elementi presenti nel vettore. Il mio problema è che se questi elementi sono degli oggetti dovrei richiamare il loro distruttore. Come faccio a capire se gli elementi del mio vettore sono degli oggetti(e quindi richiamo il loro distruttore) o non lo sono?

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Per la precisione ti servirebbe sapere se il tipo è un pod.
    Dipende dal compilatore che usi, Se è Vc++ Express Sp1 puoi usare l'header <type_traits> e un costrutto del genere. Anche G++ ultime versioni lo supporta.
    Puoi verificarlo tentando di includere l'header indicato.
    codice:
       if (!std::tr1::is_pod<T>::value) {
           p->T::~T();
       }
    Altrimenti devi ricorrere all'overload delle funzioni.

    codice:
    template <typename T> 
    inline void destroy(T* p) {
        p->T::~T();
    }
    // specializzazione per i tipi base.
    
    inline void destroy(void*) {};
    inline void destroy(void**) {};
    inline void destroy(void***) {};
    
    inline void destroy(int*) {};
    inline void destroy(int**) {};
    inline void destroy(int***) {};
    
    etc.
    Per ognuno dei tipi fondamentali del linguaggio (void, char, wchar_t, short, int, long, double, float) sia in versione signed, sia in versione unsigned.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    Per quanto riguarda la tua seconda versione, e se è una struttura come faccio a saperlo? richiamerei un distruttore di una struttura andando per esclusione.
    Ho la possibilità di usare sia borland 2010 e visual studio 2008

  4. #4
    Originariamente inviato da shodan
    Per la precisione ti servirebbe sapere se il tipo è un pod.
    Dipende dal compilatore che usi, Se è Vc++ Express Sp1 puoi usare l'header <type_traits> e un costrutto del genere. Anche G++ ultime versioni lo supporta.
    Puoi verificarlo tentando di includere l'header indicato.
    codice:
       if (!std::tr1::is_pod<T>::value) {
           p->T::~T();
       }
    Altrimenti devi ricorrere all'overload delle funzioni.

    codice:
    template <typename T> 
    inline void destroy(T* p) {
        p->T::~T();
    }
    // specializzazione per i tipi base.
    
    inline void destroy(void*) {};
    inline void destroy(void**) {};
    inline void destroy(void***) {};
    
    inline void destroy(int*) {};
    inline void destroy(int**) {};
    inline void destroy(int***) {};
    
    etc.
    Per ognuno dei tipi fondamentali del linguaggio (void, char, wchar_t, short, int, long, double, float) sia in versione signed, sia in versione unsigned.
    Grande!!! funziona! grazie

  5. #5
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da darth fener
    Per quanto riguarda la tua seconda versione, e se è una struttura come faccio a saperlo?
    Richiamerei un distruttore di una struttura andando per esclusione.
    In quel caso il compilatore dovrebbe essere abbastanza furbo da capire se una struttura ha il distruttore o no. Puoi comunque scrivere una funzione destroy() specifica per quella data struttura.

    Ho la possibilità di usare sia borland 2010 e visual studio 2008
    Borland 2010 (se non ricordo male) ha già l'header <type_traits> quindi puoi usare la prima versione. Per Visual Studio 2008 dovrebbe essere presente con il service pack 1 (dico dovrebbe perché nella Versione Express Sp1 c'è.)

    Da notare che la prima versione è leggermente più efficiente perché la scelta può essere fatta a compile time e non a run time:

    codice:
        template <typename T, bool pod_type = true>
        struct disposer {
            static void destroy(T* ptr) { /* per i pod non serve */ }
        };
    
        template <typename T>
        struct disposer<T,false> {
            static void destroy(T* ptr) { 
    	    ptr->T::~T(); // con borland può essere necessario scrivere: p->~T() 
    	}
         }
    
        // il compilatore sceglie a compile time la versione da usare.
        template <typename T>    
        void qualcosa(T* p) {
            disposer< std::tr1::is_pod< T >::value >:: (destroy(p));
        }
    Per POD si intende un tipo di dato compatibile C ovviamente. Quindi niente costruttori, distruttori, public: private etc.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  6. #6
    Scusa, allora mi riconosce è o non è un pod, per richiamare il distruttore non mi funziona. Ho
    fatto:

    codice:
    template <class T>
    void VettoreDinamico<T>::destroy(T* p)
    {
        p->T::~T();
    }
    
    template <class T>
    void VettoreDinamico<T>::clear()
    {
       size = 0;
       if(!tr1::is_pod<T>::value)
       {
           for(unsigned i=0;i<size;i++)
           {
               destroy(ptr+i);
           }
       }
    }
    e mi dice:
    [BCC32 Error] VettoreDinamico.h(72): E2045 Destructor name must match the class name
    Full parser context
    main.cpp(31): decision to instantiate: void VettoreDinamico<Prova>::destroy(Prova *)
    --- Resetting parser context for instantiation...
    main.cpp(1): #include VettoreDinamico.h
    VettoreDinamico.h(12): class VettoreDinamico<T>
    VettoreDinamico.h(71): parsing: void VettoreDinamico<Prova>::destroy(Prova *)

  7. #7
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da darth fener
    Scusa, allora mi riconosce è o non è un pod, per richiamare il distruttore non mi funziona. Ho
    fatto:
    Questo conferma il mio sospetto.
    Modifica così:
    codice:
    template <class T>
    void VettoreDinamico<T>::destroy(T* p)
    {
    #ifdef ( __BORLANDC__ ) 
        p->~T();
    #else
        p->T::~T();
    #endif
    }
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  8. #8
    niente, ho fatto come mi hai detto p->~T() e funziona.

    Grazie. Ciao

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.