Visualizzazione dei risultati da 1 a 3 su 3
  1. #1
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    62

    [C++] Ereditarieta' e dynamic_cast<>

    Ciao a tutti,
    ho un problema, sostanzialmente logico.
    Ho implementato una semplice classe Bin_tree e ora mi ritrovo a dover crearne una nuova ( Redblack_tree ) utilizzando Bin_tree come base.
    Questa e' la classe base:

    codice:
    template<class T1> class Bin_tree {
    public:
    	enum { NOT_FOUND = -10, ALREADY_EXIST = -9 };
    	Bin_tree() : empty(true) {}
    	virtual int store(const T1&);
    	int search(const T1&);
    	T1* get_ptr(int);
    	virtual void remove(int);
    	void destroy();
    	virtual void print();
    	bool is_empty() { return empty; }
    	virtual ~Bin_tree() {}
    protected:
    	Tnode<T1>* get_node(int index) { return nodes[index]; }
    	bool is_error_code(int index) { return index < 0 ? true : false; }
    	virtual Tnode<T1>* make_node() { return new Tnode<T1>; }
    private:
    	/* ... */
    	bool empty;
    	std::vector<Tnode<T1>*> nodes;		// required for indexing.
    };
    Come si puo' immaginare la classe si basa sull' utilizzo di oggetti Tnode<>* (nodi dell' albero).
    Questa sarebbe invece la classe derivata:

    codice:
    template<class T1> class Redblack_tree : public Bin_tree<T1> {
    public:
    	Redblack_tree() : Bin_tree<T1>() {}
    	virtual int store(const T1&);
    	virtual void remove(int);
    	virtual void print();
    protected: // Rbtnode<> e' derivato pubblicamente da Tnode<> .
    	virtual Tnode<T1>* make_node() { return new Rbtnode<T1>; }
    };
    I Tnode<>* sono dei puntatori a nodi progettati per il classico albero binario, nel momento in cui un utente deve implementare qualcosa come un Redblack_tree, questo dovra' anche preoccuparsi di fornire un nodo adeguato ( di tipo derivato da Tnode<> ), come Rbtndoe<>, che aggiunge la nozione di colore ( quindi solamente un mebro di tipo int in piu' ).

    Se un membro di una classe derivata vuole un puntatore ad un nodo, questa deve chiamare il membro della classe base get_ptr(), che pero' restituisce un Tnode<>* generico; quindi se per esempio un metodo di Redblack_tree dovesse accedere alla nozione di colore di un Tnode<>*, questa dovrebbe castare il puntatore attraverso un dynamic_cast<Rbtnode<T>* >(some_tnode), per esempio :

    codice:
    template<class T1> int Redblack_tree<T1>::store(const T1& obj)
    {
    	bool is_root = this->is_empty();
    	int obj_index = Bin_tree<T1>::store(obj);
    	if ( is_root )
    		dynamic_cast<Rbtnode<T1>* >(this->get_node(obj_index))->color = Rbtnode<T1>::black;
    	/* ... */
    }
    Come posso evitare il dynamic_cast<> ?

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Non puoi evitare un cast. Specie se vuoi accedere alle variabili e non alle funzioni virtuali delle classi derivate da TNode<>.

    Se ti preoccupa la "lentezza" del dynamic_cast potresti fornire a TNode<> una funzione virtuale per identificare il nodo e fare uno static_cast controllato (il DOM XML funziona così). Però se inizi ad avere molte derivate la cosa si complica e occorre ponderare se ne vale la pena.
    E' il modo di operare di Java ( e Smalltalk se non ricordo male).
    Derivare tutti gli oggetti da una classe comune e poi fare cast ovunque.
    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
    Jul 2008
    Messaggi
    62
    Ciao shodan,
    grazie del consiglio; penso che rimpiazzero' il dynamic_cast<> con uno static_cast<>, dato che, tuttavia, quando eseguo il cast l' oggetto in questione e' appena stato costruito, e' quindi impossibile che il dynamic_cast fallisca.


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