Rappresentazione in memoria di un oggetto complesso

di il
6 risposte

Rappresentazione in memoria di un oggetto complesso

Dichiarando una struttura:
struct campione 
{
  unsigned int indice;
  double vaore;
}obj;
Io so che "indice" occupa i primi 4 byte della memoria occupata da obj, e "valore" i successivi 8 (ipotizzando che i campi vengano allineati su non più di 4 byte).
In quali condizioni posso dire la stessa cosa di una classe?

Ad esempio, se in C++ scrivo:
class campione 
{
public:
  unsigned int indice;
  double vaore;
}obj;
In teoria quanto detto sopra è ancora valido, dal momento classi e strutture sono la stessa cosa, salvo il fatto che dove non espressamente specificato i membri delle strutture sono public,
mentre i membri delle classi sono private. Ma se io inizio ad avere cose più elaborate, se inserisco dei metodi, o se derivo la classe, su quali certezze posso fare affidamento?

Esiste in pratica, che voi sappiate, un metodo per accedere al blocco di memoria in cui un oggetto memorizza i membri dato, e sapere quanto è lungo?

Michele

6 Risposte

  • Re: Rappresentazione in memoria di un oggetto complesso

    Nessuno. Ovvero è implementazione definita. Prendi anche l'esempio + semplice: il double, nessuno ti garantisce che terrà 8 byte in memoria. il sizeof lo applichi solo ad oggeti POD (plain old data) e se inizi a mettere dei metodi l'oggetto in questione non è + POD.


    http://stackoverflow.com/questions/146452/what-are-pod-types-in-c
  • Re: Rappresentazione in memoria di un oggetto complesso

    Molto interessante! Grazie.

    Dunque, se io volessi salvare un oggetto in un file (o in un blocco di memoria contiguo, trattato al pari di un file), dovrei crearmi un metodo virtuale che va ad "enumerare" tutti i campi, copiandoli uno alla volta, ad esempio:
    
    class sample
    {
      unsigned int indice;
      double valore;
    
      voif Copia(unsigned char *dest)
      {
        unsigned char *p = dest
        *(unsigned int*)p = indice;
        p += sizeof(unsigned int);
        *(double*)p = valore;
      };
    };
    Sarei curioso di conoscere il parere di chi abbia esperienza di programmazione c++.
    Io uso questo approccio da una vita, ma in C. In C++ mi aspetterei di trovare qualcosa di più elegante.

    Michele
  • Re: Rappresentazione in memoria di un oggetto complesso

    In C++ esiste il copy constructor e copy assignement
    
    foo & operator=(const foo & rhs);
    foo(const foo & rhs);
    
    Volendo puoi usare reinterpret_cast per cerca di trasformare un oggetto in un altro ma devi essere sicuro di quello che fai.
    Infine per scrivere/leggere strutture/classi da file si usano i overload dei operatori << e >> delle classi iostream.
  • Re: Rappresentazione in memoria di un oggetto complesso

    Approfondisco il reiterpret_cast, grazie...
  • Re: Rappresentazione in memoria di un oggetto complesso

    Alla fine ho optato per questa soluzione.

    All'interno della classe, dichiaro un membro "buffer", come puntatore a byte (unsigned char), che contterrà il mio "blocco di memoria contigua".
    Fuori dalla classe dichiaro la struttura che mi rappresenta appunto la struttura del mio blocco di memoria.
    Infine aggiungo alla classe una serie di metodi per l'accesso ai singoli campi della struttura, la quale fa un reiterpret_cast del buffer a puntatore a struttura:
    
    struct s_sample
    {
      unsigned int indice;
      double valore;
    };
    
    class CSample
    {
      unsigned char *buffer;
    
    public:
      unsigned int Indice() {return reinterpret_cast<struct s_sample*>(buffer)->indice;};
      double Valore() {return reinterpret_cast<struct s_sample*>(buffer)->valore;};
    
      void Indice(unsigned int val) {reinterpret_cast<struct s_sample*>(buffer)->indice = val;};
      void Valore(double val) {reinterpret_cast<struct s_sample*>(buffer)->valore = val;};
    }
    
    
    Nel momento in cui voglio specializzare tale classe, prima definisco una nuova struttura, aggiungendo i campi che mancano, poi derivo la classe, aggiungendo i metodi di accesso ai nuovi dati:
    
    struct sample2
    {
      struct sample base;
      char [50] descrizione;
    };
    
    class CSample2 : public CSample
    {
      GetDescrizione(char *buf) {strcpy(buf,reinterpret_cast<struct sample2*>(buffer)->descrizione);};
      SetDescrizione(char *buf) {strcpy(reinterpret_cast<struct sample2*>(buffer)->descrizione,buf);};
    };
    
    Ovviamente, ogni classe sarà responsabile di allocare la memoria coerentemente con la dimensione della struct a cui si riferisce.

    Opinioni? Consigli?

    Michele
  • Re: Rappresentazione in memoria di un oggetto complesso

    Utilità di questo codice? Secondo me nessuna e non è detto che funzioni. indice e valore sono valori del primo struct che non sono riconducibili al membro struct sampe base della classe CSample2. Insomma io non ho ancora capito cosa vorresti fare.
Devi accedere o registrarti per scrivere nel forum
6 risposte