Autore Topic: Richiamo dei costruttori della superclasse  (Letto 1833 volte)

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Richiamo dei costruttori della superclasse
« il: 08 Luglio 2011, 21:59:40 »
Ciao a tutti,

considerate il seguente codice:

Codice: [Seleziona]
class A : public B
{
 public:
 //costruttore
 A();
 //distruttore
 ~A();
};

A::A()
{
 cout<<sono nel costruttore!"<<endl;
}

Ecco, vorrei sapere se, nell'esempio di sopra, il costruttore di A, richiama esplicitamente il costruttore (vuoto o senza argomenti) di B.
Mi sembra che questo sia il comportamento normale (almeno in Java dovrebbe essere così)...
A questo punto mi interesserebbe richiamare il costruttore di B esplicitamente e NON come prima operazione da effettuarsi nel costruttore di A. Vorrei poter fare qualcosa del genere:

Codice: [Seleziona]
A::A()
{
 [Operazioni varie di inizializzazione]
 B();
}

Che io sappia in Java questo non si può fare (il costruttore della superclasse deve essere invocato come prima operazione nel costruttore della classe figlia), mi chiedo se invece è possibile in C++ ...
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Richiamo dei costruttori della superclasse
« Risposta #1 il: 08 Luglio 2011, 22:18:59 »
Citazione da: "dsar"
Ti sconsiglio di utilizzare le supercall, perché causano il Fragile Base Class problem.
Ti consiglio invece di utilizzare le relazioni di subtyping e non subclassing.

Uhmm vediamo se ho capito.
Praticamenete non mi conviene subclassare B ma creare una oggetto di classe B all'interno di A. (Fare in modo che A contenga B)

Giusto?
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Richiamo dei costruttori della superclasse
« Risposta #2 il: 08 Luglio 2011, 22:26:26 »
Citazione da: "dsar"
Citazione da: "clros"
Citazione da: "dsar"
Ti sconsiglio di utilizzare le supercall, perché causano il Fragile Base Class problem.
Ti consiglio invece di utilizzare le relazioni di subtyping e non subclassing.

Uhmm vediamo se ho capito.
Praticamenete non mi conviene subclassare B ma creare una oggetto di classe B all'interno di A. (Fare in modo che A contenga B)

Giusto?
No, quella è la relazione HAS di containment, ed è effettivamente l'unico modo safe per avere il code reuse (tramite il delegation). Quindi tu devi per forza riutilizzare il codice?
Prima stabilisci se la relazione delle tue classi è un IS o un HAS.

In realtà io vorrei che la mia (sub)classe A esponga la stessa interfaccia di B (più eventuali altri metodi definiti in A), quindi credo che che sia una relazione IS.
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5293
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
Re: Richiamo dei costruttori della superclasse
« Risposta #3 il: 08 Luglio 2011, 22:37:20 »
Per chiamare il costruttore di una superclasse, in C++, devi usare gli inizializzatori di istanza:

Codice: [Seleziona]
Figlio::Figlio()
 : Padre()
{
 // resto del costruttore

}

Gli inizializzatori di istanza partono prima del costruttore, quindi quella cosa che chiedi non si può fare in un punto qualsiasi del codice.

Piuttosto, potresti spostare il codice di inizializzazione in una funzione privata init(); così puoi fare:
Codice: [Seleziona]
Figlio::Figlio()
{
  init();
}

Padre::Padre()
{
  init();
}

Padre::init()
{
  // codice padre
}

Figlio::init()
{
// codice figlio #1
Padre::init();
// codice figlio #2
}


Non ci sono altri modi
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Richiamo dei costruttori della superclasse
« Risposta #4 il: 08 Luglio 2011, 23:03:56 »
Citazione da: "dsar"
Citazione da: "clros"
In realtà io vorrei che la mia (sub)classe A esponga la stessa interfaccia di B (più eventuali altri metodi definiti in A), quindi credo che che sia una relazione IS.

Se dici "esponga la stessa interfaccia" allora parliamo di subtyping che non prevede subclassing (ovvero il code reuse), quindi non puoi fare una supercall.

La relazioni tra classi devono avvenire solo tramite interfacce, la baseclass o specializzazioni di quest'ultima devono essere sempre di tipo astratto, solo la classe finale deve essere concreta.

Nel mio caso non è possibile, la superclasse è una classe concreta...
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5293
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
Re: Richiamo dei costruttori della superclasse
« Risposta #5 il: 08 Luglio 2011, 23:07:40 »
Citazione da: "dsar"
E' meglio tuttavia che il codice dei costruttori sia del tutto separato e che la relazione sia di sola interfaccia.

Concordo assolutamente, si può sicuramente trovare un modo per refattorizzare quel codice eliminando le dipendenze dei costruttori.
Solitamente questi problemi sorgono quando le classi iniziano ad incasinarsi in seguito a modifiche ed estensioni ripetute nel tempo.

Una classe scritta ex novo non dovrebbe mai avere quel tipo di dipendenza, anche perchè, se vai a modificare la classe padre, automaticamente potresti rompere il codice delle classi figlie e viceversa! Secondo me bisogna prendere il progetto, fermarsi un attimo e fare una bella pulizia e refactoring dei punti più incasinati.
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Richiamo dei costruttori della superclasse
« Risposta #6 il: 08 Luglio 2011, 23:14:32 »
Citazione da: "TheKaneB"
Citazione da: "dsar"
E' meglio tuttavia che il codice dei costruttori sia del tutto separato e che la relazione sia di sola interfaccia.

Concordo assolutamente, si può sicuramente trovare un modo per refattorizzare quel codice eliminando le dipendenze dei costruttori.
Solitamente questi problemi sorgono quando le classi iniziano ad incasinarsi in seguito a modifiche ed estensioni ripetute nel tempo.

Una classe scritta ex novo non dovrebbe mai avere quel tipo di dipendenza, anche perchè, se vai a modificare la classe padre, automaticamente potresti rompere il codice delle classi figlie e viceversa! Secondo me bisogna prendere il progetto, fermarsi un attimo e fare una bella pulizia e refactoring dei punti più incasinati.

Allora, la class padre non l'ho scritta io, esiste già (per cui, anche avendo a disposizione il codice, non voglio assolutamente toccarla).
Il progetto non credo sia affatto complesso, devo solo realizzare uno sottoclasse di questa. (ma ads mi stanno venendo molti dubbi)

Scusate ragazzi,  ads mi sfugge la differenza tra subclassing e subtyping... :-(
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Offline clros

  • ASM Lover
  • *****
  • Post: 457
  • Karma: +3/-1
    • Mostra profilo
Re: Richiamo dei costruttori della superclasse
« Risposta #7 il: 08 Luglio 2011, 23:31:01 »
Citazione da: "dsar"
Citazione da: "clros"
Allora, la class padre non l'ho scritta io, esiste già (per cui, anche avendo a disposizione il codice, non voglio assolutamente toccarla).
Il progetto non credo sia affatto complesso, devo solo realizzare uno sottoclasse di questa. (ma ads mi stanno venendo molti dubbi)

Scusate ragazzi,  ads mi sfugge la differenza tra subclassing e subtyping... :-(
E' sicuro una classe padre o è una classe final che di suo ha già adottato delle classi interfacce? Hai la documentazione?

Subclassing è implementation inheritance, erediti interfaccia e codice.

Subtyping è interface inheritance, erediti solo l'interfaccia.

Allora non mi sfuggiva la differenza..diciamo che non l'ho mai conosciuta! :-(

La classe padre è la classe thread di C++0x.
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »
Claudio CP La Rosa

Tags: