Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Istanziare classe derivata conoscendo il prototipo della classe base
Forum - C/C++ - Istanziare classe derivata conoscendo il prototipo della classe base

Avatar
Exor (Normal User)
Rookie


Messaggi: 30
Iscritto: 29/08/2009

Segnala al moderatore
Postato alle 22:09
Domenica, 21/11/2010
salve ragazzi,

ho un problemino.

ho una libreria dove c'è sviluppata una classe base con questo modello
Codice sorgente - presumibilmente C#

  1. classe Base {
  2.  private:
  3.   ...
  4.  public:
  5.   virtual void OnError();
  6.   void init () { ... }
  7.   ...
  8. }



e una funzione
Codice sorgente - presumibilmente C/C++

  1. void callOnErr () {
  2.  
  3. }



dove vorrei istanziare la classe derivata che però non è dichiarata nella stessa libreria
Codice sorgente - presumibilmente C#

  1. class Derivata : public Base {
  2.   public:
  3.     void OnError() { ... }
  4. }



esiste un modo per istanziare nella funzione la derivata che però che può avere un nome variabile (tipo usando una macro DERIVATA(nomeclasse))

grazie :)

Ultima modifica effettuata da Exor il 21/11/2010 alle 22:15
PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 2:40
Lunedì, 22/11/2010
non si capisce bene la domanda...
cerca di spiegarla meglio, con qualche esempio e spendendo qualche parola in più. Prendi pure tutto il tempo e lo spazio che ti serve. Più tempo dedichi a formalizzare la domanda, più velocemente arriverà la risposta corretta.

;-)

PM Quote
Avatar
napco (Normal User)
Pro


Messaggi: 64
Iscritto: 16/04/2010

Segnala al moderatore
Postato alle 12:10
Lunedì, 22/11/2010
Cioè... Vorresti creare un oggetto a partire dal nome (stringa) della classe? I modi sono due: o ti usi i templates (scelta consigliata) oppure usi un void * ed una macro, ma questo ti obbligherà ad eseguire un type cast ogni volta che vuoi chiamare un metodo.

Codice sorgente - presumibilmente C++

  1. #define DERIVATA(nome) new nome()
  2.  
  3. class Blah
  4. {
  5. ...
  6. };
  7.  
  8. void *blah = DERIVATA("Blah");



Questa è l'idea generale, ma non l'ho mai provata e non ho poi tutta questa confidenza con il preprocessore, percui non sono sicuro che funzioni. E comunque te lo sconsiglio a priori.

Ultima modifica effettuata da napco il 22/11/2010 alle 12:11
PM Quote
Avatar
lorenzo (Normal User)
Guru


Messaggi: 1178
Iscritto: 15/04/2008

Segnala al moderatore
Postato alle 20:13
Lunedì, 22/11/2010
Usare una macro in C++ non ha senso....ci sono apposta i template.

Codice sorgente - presumibilmente C++

  1. #include <iostream>
  2.  
  3. class A
  4. {
  5. public:
  6.         virtual void print() { std::cout << "Base\n"; }
  7. };
  8.  
  9. class B: public A
  10. {
  11. public:
  12.         virtual void print() { std::cout << "Derivata B\n"; }
  13. };
  14.  
  15. class C: public A
  16. {
  17. public:
  18.         virtual void print() { std::cout << "Derivata C\n"; }
  19. };
  20.  
  21. template <typename T>
  22. void CallOnErr()
  23. {
  24.         T obj;
  25.         obj.print();
  26. }
  27.  
  28. int main()
  29. {
  30.         CallOnErr<A>();
  31.         CallOnErr<B>();
  32.         CallOnErr<C>();
  33.         return 0;
  34. }




PM Quote
Avatar
Exor (Normal User)
Rookie


Messaggi: 30
Iscritto: 29/08/2009

Segnala al moderatore
Postato alle 20:26
Lunedì, 22/11/2010
Testo quotato

Postato originariamente da lorenzo:

Usare una macro in C++ non ha senso....ci sono apposta i template.

Codice sorgente - presumibilmente C++

  1. #include <iostream>
  2.  
  3. class A
  4. {
  5. public:
  6.         virtual void print() { std::cout << "Base\n"; }
  7. };
  8.  
  9. class B: public A
  10. {
  11. public:
  12.         virtual void print() { std::cout << "Derivata B\n"; }
  13. };
  14.  
  15. class C: public A
  16. {
  17. public:
  18.         virtual void print() { std::cout << "Derivata C\n"; }
  19. };
  20.  
  21. template <typename T>
  22. void CallOnErr()
  23. {
  24.         T obj;
  25.         obj.print();
  26. }
  27.  
  28. int main()
  29. {
  30.         CallOnErr<A>();
  31.         CallOnErr<B>();
  32.         CallOnErr<C>();
  33.         return 0;
  34. }






come fai a chiamare CallOnErr<B>(); se non sai come si chiama B :)

CallOnErr() si trova in una libreria che non ha prototipo di questa classe derivata, si sa solo che è derivata da Base di cui conosce il prototipo

è questo il senso della domanda.

la domanda di fondo è: come faccio a utilizzare un membro di una classe derivata da Base, ma senza sapere il nome della classe derivata ?

usando le wxWidgets l'ho visto fare con la classe wxApp:
c'è la classe base wxApp che ha 2 metodi virtuali OnInit ed OnEnd e questi vengono definiti in una classe derivata ad esempio Main ed usando una macro IMPLEMENT_APP(nomeclasse) vengono usati i 2 metodi dichiarati in nomeclasse (IMPLEMENT_APP(Main))

Ovviamente userà qualche espediente tipo definire una funzione ad hoc, vi chiedo solamente se magari qualcuno ne ha mai avuto bisogno e conosce un metodo per fare ciò.

grazie


EDIT:

Finalmente ho trovato la soluzione :) leggendo il sorgente di wxApp ho capito come fare usando la macro.

grazie lo stesso a tutti, gentilissimi

Ultima modifica effettuata da Exor il 22/11/2010 alle 21:04
PM Quote