Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    7

    [C++] Chiamare lo stesso metodo per tante classi... come?

    Sto usando il C++builder del Borland Dev.Studio 2006, ma penso che il problema sia indipendente dall'ambiente di sviluppo.
    Premetto che, essendo io un programmatore "nato" col VB6, magari sto facendo una domanda "stupida", ma io non ci riesco....

    Cosa ho (semplifico molto):

    Una classe base, che deriva da una classe "standard" del C++builder
    codice:
    class cBase: public TObject { 
      private:
    	char	cNome[0xFF];
    	String	__fastcall GetNome() {return (String)cNome;};
    	void	__fastcall SetNome(String sNome) {strncpy(cNome,sNome.c_str(),0xfE);cNome[0xff]=0;};
    	int iIndice;
      public:
    	String	__fastcall StringaDati(){return "";};
    	__property String		Nome = {read=GetNome, write=SetNome};
    	__property int		Indice = {read=iIndice, write=iIndice};
    };
    una decina di classi (cDerivata1, cDerivata2,...) derivate dalla cBase, che ridefiniscono il metodo "StringaDati", e una "Collection" (una lista) che, dato l'indice, restituisce un "TObject*".

    Al momento, se voglio chiamare il metodo "StringaDati" per tutte le classi istanziate devo sapere che tipo di classe c'è al dato indice e castare il puntatore al tipo giusto:
    supponiamo che le prime 10 siano cDerivata1, dalla 10 alla 20 siano cDerivata2 ecc...
    codice:
    for (j=0;j<100;j++) {
    	if (j<10) {
    		Dati = (cDerivata1*)Lista->Items[j]->StringaDati();
    		continue;
    	}
    	if (j<20) {
    		Dati = (cDerivata2*)Lista->Items[j]->StringaDati();
    		continue;
    	}
    	....
    }
    La cosa è evidentemente orrenda.

    Quello che mi serve è un modo per chiamare il metodo "StringaDati" fregandomene del Tipo di classe a cui sto puntando.
    In pratica, qualcosa tipo:
    codice:
    for (j=0;j<100;j++) {
    	Dati = (qualcosa*)Lista->Items[j]->StringaDati();
    }
    lasciando che sia qualcosa a sapere quale "versione" di StringaDati serve.

    Non ho capito se 'sta cosa si fa con le "interfacce", e se sì come si fa....
    ....qualcuno mi da una mano?

  2. #2

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    7
    Originariamente inviato da MacApp
    rendi il metodo StringaDati virtual.
    c'ho provato:
    codice:
    virtual String	__fastcall StringaDati();
    Ottengo un errore dal linker:

    [Linker Error] Error: Unresolved external '__fastcall cBase::StringaDati()' referenced from C:\SOURCE\\_OBJ\MYCLASSES.OBJ

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da parduz
    c'ho provato:
    codice:
    virtual String	__fastcall StringaDati();
    Ottengo un errore dal linker:

    [Linker Error] Error: Unresolved external '__fastcall cBase::StringaDati()' referenced from C:\SOURCE\\_OBJ\MYCLASSES.OBJ
    Se non è virtuale pura devi lasciare un corpo alla funzione.
    codice:
    virtual String	__fastcall StringaDati() { return "";}
    Se invece la vuoi virtuale pura costringendo a ridefinirla per ogni classe derivata
    codice:
    virtual String	__fastcall StringaDati()=0;
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    7
    Ok, lunedì ci provo....
    ...nel frattempo ti chiedo se ho capito bene:
    se la rendo virtuale (pura o meno.... qualunque cosa questo significhi ), chiamando
    codice:
    Dati = (cBase*)Lista->Items[j]->StringaDati();
    viene eseguita la funzione definita nella classe derivata "giusta"?

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Una funzione virtuale pura costringe a derivare la classe quindi:
    codice:
       cBase cb;
    produrrà un errore di compilazione. (Che dovrebbe accadere ugualmente visto che TObject mi sembra si possa solo usare come puntatore).
    Sempre se non ricordo male Lista->Items[j] dovrebbe restituire un puntatore void.
    Dovresti usarla così:
    codice:
    Dati = ( (cBase*)Lista->Items[j] )->StringaDati();
    per fare quello che ti serve.
    viene eseguita la funzione definita nella classe derivata "giusta"?
    Si, è alla base del polimorfismo.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  7. #7
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    7
    ...errore di compilazione [...] visto che TObject mi sembra si possa solo usare come puntatore
    In C++Builder è la classe "base" da cui derivare tutto (se vuoi che venga "gestito" in automatico dal "sistema"). Questo è anche il motivo per cui la mia lista (che è l'Owner degli oggetti) restituisce dei TObject*.

    Si, è alla base del polimorfismo.
    Sei stato veramente d'aiuto. Purtoppo manco di teoria, in questi casi

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