Visualizzazione dei risultati da 1 a 4 su 4
  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826

    [c++]composite e grafi in gen.

    ciao.
    Ho un grafo di oggetti implementato con il pattern composite.
    Il mio problema è che ho tre tipi di oggetti leaf(senza figli) e vorrei distinguerli.
    Sicuramente è una cosa banale ma non l'ho mai capita bene.

    Posso:
    1)usare rtti
    2)usare una funzione che mi ritorna il codice o l'identificativo del tipo di classe, leggerlo e comportarmi di conseguenza
    3)implementare un metodo o una serie di metodi(ereditati da una classe base che li espone con virtual) che ritornano null e non fanno niente se la classe che li contiene non è del quel tipo interessato, mentre eseguono il comportamento "corretto" (definito ) se sono di quella classe (mi sembra la migliore , comunque chiedo)o ????

    secondo voi cosa è meglio?

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Bella domanda a cui non è semplice dare una risposta.
    Diciamo che ci sono varie filosofie a riguardo e tutte che fanno a pugni tra loro.

    RTTI è lenta visto che il compilatore deve guardarsi le varie vtable delle classi, quindi se la usi parecchio le prestazioni iniziano a risentirne. Diciamo che va bene se proprio sei costretto ad accedere a metodi specifici di quell'oggetto, non astratti da funzioni virtuali, una volta a morte di papa.

    Il metodo 2 è la RTTI dei poveri. In pratica devi fare tu quello che il compilatore farebbe per te. E' più veloce, ma ti costringe ad aggiungere un metodo, una eventuale enumerazione per riconoscerli e che tende a crescere all'aumentare delle derivazioni. Però se la derivazione è a diamante o public virtual, tutti i cast falliscono a eccezione del dynamic_cast<> (e si torna nel caso 1).

    Il metodo 3 ti costringe a controllare i valori restituiti (se ce ne sono) per verificare se siano validi, ma hai il vantaggio che se un domani aggiungi un tipo di dato (purché non aggiunga altre funzioni virtuali), il tuo programma non fa una piega: derivi e morta li.
    Il problema diventa appunto quando il tuo tipo di dato deve aggiungere altre funzioni virtuali che costringono a modificare l'interfaccia solo per lui. Alla fine potresti trovarti un'interfaccia mastodontica da gestire perché uno ha bisogno di una cosa e un'altro di un'altra cosa ancora.

    Questo in generale.
    Nel caso specifico, se tu hai solo tre classi derivate e non prevedi di metterne altre, io per me userei il punto 3 senza pensarci due volte.
    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.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    ciao .
    Ho ripescato questa discussione perchè mi sono trovato di nuovo a creare un pattern composite.
    Questa volta il problema sono gli smart pointer , infatti vorrei utilizzarli.
    Il problema che mi si è posto di fronte sono le circular reference , ovvero quando uno smart pointer è inserito(incapsulato) in un altra classe di cui si crea uno smart pointer.
    ad es io ho un applicazione in cui sono definiti gli smart pointer come Pointer<class>.Quando faccio un typedef ad es :
    codice:
    class node : NodeBase
    {
    
    };
    typedef Pointer<node> NodePtr // creo lo smart pointer NodePtr
    se ho nella stessa classe ad es :
    codice:
    class node
    {
    std::vector<NodePtr> m_child;
    NodePtr m_parent;
    };
    devo rompere la circular reference a manina con una funzione che itera tutto il grafo e rilascia le risorse di m_parent per ogni nodo.

    Dopo gli oggetti NodePtr funzionano correttamente e le risorse vengono rilasciate in modo corretto.

    ora ho due problemi:
    1)ho definito una classe NodeBase in cui secondo il tuo consiglio ho inserito tutte le funzioni virtuali.
    il dubbio è : quando utilizzare ad es un
    typedef Pointer<node> NodePtr ?
    o un
    typedef Pointer<NnodeBase> NodeBasePtr?
    nelle classi derivate?
    in pratica nelle classi derivate da nodebase è meglio usare un

    insertNode(NodeBasePtr)
    o
    insertNode(NodePtr)

    ??

    2)come gestire un NodePtr all'interno della classe Node?
    Mitaly mi aveva suggerito di usare una forward declaration cosi :
    http://forum.html.it/forum/showthrea...hlight=forward vado in contro a qualche problema con questa dichiarazione ?
    creo di no perchè Mitaly mi ha sempre consigliato bene , ma non si sa mai.
    In particolare ho una variabile membro vector<CMeshPtr> m_Meshes dove CMesh deriva da NodeBase e non riesco ad inserire valori in questa collezione.
    Dove devo cercare l'errore?

    ma è piu corretto in questa classe utilizzare i nodebaseptr forse?
    ma ho letto che meno castsi eseguono meglio è (genericamente).

    grazie

  4. #4
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    ps. se uso le classi virtuali nella classe base cnode è chiaro che le funzioni delle classsi derivate dovranno utilizzare la stessa firma , quindi dovro' utilizzare CNodeBasePtr nelle classi derivate che fanno l'override delle funzioni virtual della classe base.
    Ma quando utilizzo uno smart pointer che deriva da CNodeBase ad es CNodeMesh e lo passo come parametro a una funzione che ha un parametro CNodeBase è come effettuare un cast?
    perche vorrei che il grafo avesse le massime prestazioni per quello che deve fare.

    grazie.

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.