Pagina 2 di 2 primaprima 1 2
Visualizzazione dei risultati da 11 a 18 su 18

Discussione: [C++] Nomenclatura

  1. #11
    Originariamente inviato da lolide
    Infatti non devi riallocare una classe. E' una cosa da fare solamente con i tipi primari come dice MItaly che comunque secondo me è una cosa fattibilissima, cioè:

    se volessi creare una classe String come con Java, alla fine devi avere sempre un puntatore interno di char che mantiene la stringa. Per ridimensionare automaticamente la String, basta fare realloc sull'array interno di char

    Se volessi fare un'array di String dinamico (StringArray), come fa std::vector, basta tenere in questa classe un puntatore a String. Usi malloc(), realloc() e free() per gestirlo e poi li inizializzi con il loro costruttore.
    Per le classi string ok. Ma se volessi creare una classe tamplate che mi tratta anche i tipi non primitivi malloc(), realloc() e free() non vanno più bene, no?!

  2. #12
    Originariamente inviato da lolide
    se volessi creare una classe String come con Java, alla fine devi avere sempre un puntatore interno di char che mantiene la stringa. Per ridimensionare automaticamente la String, basta fare realloc sull'array interno di char
    Le classi string stile Java se non erro sono immutabili; ogni volta che applichi una modifica, di fatto ti viene restituita una nuova stringa. Sono le classi string stile C++ ad essere modificabili.
    Se volessi fare un'array di String dinamico (StringArray), come fa std::vector, basta tenere in questa classe un puntatore a String. Usi malloc(), realloc() e free() per gestirlo e poi li inizializzi con il loro costruttore.
    No, string a questo punto sarebbe un tipo non POD (dato che contiene un puntatore a stringa gestito tramite costruttore e distruttore), per cui non lo puoi più trattare con malloc, realloc e free.
    Originariamente inviato da RooccoXXI
    Per le classi string ok. Ma se volessi creare una classe tamplate che mi tratta anche i tipi non primitivi malloc(), realloc() e free() non vanno più bene, no?!
    No. Se hai a che fare con tipi non POD (e se stai scrivendo un container template in linea di massima ti puoi aspettare tipi non-POD) non puoi che usare new/delete.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #13
    Originariamente inviato da MItaly
    No, string a questo punto sarebbe un tipo non POD (dato che contiene un puntatore a stringa gestito tramite costruttore e distruttore), per cui non lo puoi più trattare con malloc, realloc e free.
    Intendevo gestire il puntatore interno a String con malloc, realloc e free, non gli oggetti String.

  4. #14
    Originariamente inviato da MItaly
    No. Se hai a che fare con tipi non POD (e se stai scrivendo un container template in linea di massima ti puoi aspettare tipi non-POD) non puoi che usare new/delete.
    Come sospettavo.

    E come si fa a rievocare lo stesso comportamento di realloc con new?

    Qualcosa del genere?


    codice:
    T* array1Ptr = new T[oldSize];
    
    T* array2Ptr = new T[newSize];
    
    for(int i = 0; i <= newSize; i++)
    {
        if(i <= oldSize)
        {
           array2Ptr[i] = array1Ptr[i];
        }
        else
        {
           array2Ptr[i] = 0;
         }
    }
    
    array1Ptr = array2Ptr;

  5. #15
    Il concetto è quello, ma il limite del for è sbagliato; deve essere <, non <=. Inoltre con quel preciso codice avresti dei problemi di memory leak se viene sollevata un'eccezione al momento di creare array2Ptr, e tra l'altro ti dimentichi di deallocare array1Ptr alla fine (problemi che puoi risolvere facilmente con uno smart pointer).
    Poi, non tutti i tipi si possono inizializzare a 0, il modo generico per inizializzare un tipo al suo valore di default è assegnargli T() (costruisce un oggetto temporaneo di quel tipo e lo copia sull'elemento di destinazione).
    Va detto tuttavia che non ti serve inizializzare gli elementi oltre a quelli che già ci sono, per cui ti puoi limitare solo alla copia degli elementi "vecchi" (cosa che peraltro puoi fare direttamente la funzione std::copy).

    -EDIT-
    In realtà si può ottimizzare questo lavoro usando memoria allocata in maniera "grezza" con malloc/free e i placement new e placement delete per inizializzare solo gli elementi finora usati per davvero, ma se non sai come si usano placement new e placement delete è meglio lasciare stare.

    (edit perché prima avevo scritto una sciocchezza, non si può usare realloc con i placement new/delete)
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #16
    Originariamente inviato da MItaly
    Le classi string stile Java se non erro sono immutabili; ogni volta che applichi una modifica, di fatto ti viene restituita una nuova stringa. Sono le classi string stile C++ ad essere modificabili.
    Si intendevo quelle, grazie per la precisazione.

    Originariamente inviato da MItaly
    No, string a questo punto sarebbe un tipo non POD (dato che contiene un puntatore a stringa gestito tramite costruttore e distruttore), per cui non lo puoi più trattare con malloc, realloc e free.
    E' il puntatore all'interno di StringArray che verrà trattato con malloc() realloc() e free(), dato che è un puntatore a void, quindi solo un insieme di byte che conterrà i vari oggetti String, inizializzati normalmente con new e delete.

    Ho buttato giù questo codice (quanto mi piace *_*), una specie di template scarno e senza una completa gestione degli errori, ma almeno ti fa capire il ragionamento che seguivo ed il ragionamento che si usa con gli array, che non sono strutture particolari, ma solamente un insieme di byte come tutti gli altri tipi.

    codice:
    class Container {
    	private:
    		void* arr;
    		int dim;
    		int sing_dim;
    	public:
    		Container (int dim_el) {
    			if (dim_el < 0)
    				return;
    			sing_dim = dim_el;
    			dim = 0;
    			arr = malloc(dim_el);
    		};
    
    		void* get (int pos) {
    			if ((pos < 0) || (pos > dim))
    				return 0;
    
    			void *t = malloc(sing_dim);
    			memcpy(t, (&arr+(pos*sing_dim)), sing_dim);
    			return t;
    		};
    
    		void* append (void* elem) {
    			void* t = realloc(arr, (dim+1)*sing_dim);
    			if (t == 0)
    				return 0;
    
    			arr = t;
    			void* tocopy = dim == 0 ? arr : &arr+(dim*sing_dim);
    			memcpy(tocopy, elem, sing_dim);
    			dim++;
    			return arr;
    		};
    
                    ~Container() {
                            free(arr);
                    };
    };
    
    /* BLOCCO D'UTILIZZO */
    
    {
    	Container c(sizeof(int));
    
    	int num = 23;
    	c.append(&num);
    	num = 323;
    	c.append(&num);
            int *elem0 = (int*)c.get(0);
    	int *elem = (int*)c.get(1);
    	
            if ((elem0 == 0) || (elem == 0))
    		return 1;
    }
    Questa programmazione è stata sostituita dai template con il C++, ma secondo me rimane una bella esperienza che ti fa capire molte cose.

  7. #17
    Originariamente inviato da lolide
    E' il puntatore all'interno di StringArray che verrà trattato con malloc() realloc() e free(), dato che è un puntatore a void, quindi solo un insieme di byte che conterrà i vari oggetti String, inizializzati normalmente con new e delete.
    Gli oggetti String non sono POD, dato che contengono un puntatore a stringa gestito da loro e hanno costruttore e distruttore non banale, quindi non li puoi trattare come un insieme di byte. Che poi, all'atto pratico, se li "sposti" (non rimangono più copie dello stesso oggetto in circolazione) te la puoi cavare senza problemi è un'altra questione.
    Questa programmazione è stata sostituita dai template con il C++, ma secondo me rimane una bella esperienza che ti fa capire molte cose.
    Ti fa capire perché sono stati inventati i template.
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #18
    Più o meno ho capito!

    Nel week-end se ho tempo proverò a implementare qualcosa di simile a un contenitore per provare!

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 © 2025 vBulletin Solutions, Inc. All rights reserved.