Ciao, provo a risponderti.
La classe A alloca un area di memoria per la variabile X quando viene creata ( A* a = new A() ) e questa area contiene il valore che andrai a mettere nella variabile X.
La classe B alloca un area di memoria per la variabile X quando viene creata ( B* b = new B() ) e questa area contiene solo l' indirizzo di memoria usabile per andare a trovare il contenuto che andiamo a mettere nella variabile X.
Quindi durante l'allocazione in memoria fatta dalla "new", la classe A alloca (oltre a vari dati di organizzazione) la variabile X come area dove mettere un insieme di caratteri (il valore della stringa). In questo caso molto particolare si tratta di un dato che teoricamente non ha una lunghezza stabilita (string appunto) quindi sarà grande un certo valore n che non so (penso dipenda dal compilatore, teoricamente infinito ma praticamente no); se invece fosse stato un dato comune di lunghezza definita tipo INT, la spiegazione si sarebbe già conclusa (INT è 32 bit).
Durante l'allocazione di memoria della classe B tu allochi invece una variabile indirizzo (normalmente è grande 32 bit) che si riferirà ad un dato string (quando lo creerai) e non l' intera variabile X.
La classe B quindi conterrà uno spazio vuoto che tu alimenterai con l' indirizzo dell' oggetto string (esistente o che creerai in seguito).
La struttura ha un comportamento analogo alle classi per quanto riguarda le variabili interne, quindi valgono le stesse considerazioni.
Spero di esserti stato di aiuto.
Ciao!![]()