Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    [C++] Sostituire puntatori con shared_ptr

    Salve a tutti,
    come posso fare in modo di sostituire i puntatori tradizionali con gli shared_ptr in un codice di questo tipo ?

    codice:
    #include <iostream>
    #include <tr1/memory>
    #include <list>
    
    using namespace std;
    using namespace std::tr1;
    
    class Base;
    class Derived;
    
    typedef Base* spBase_t;
    typedef Derived* spDerived_t;
    
    class Base
    {
    public:
     int type;
    };
    
    class Derived : public Base
    {
     public:
       void print() { cout << "Hello from Derived" << endl ; } 
    };
    
    int main()
    {
      list<spBase_t> l; 			//list of ponters to Base object
      
      spBase_t  d1( new Derived() ); 	//create derived objects
      spBase_t  d2( new Derived() ); 	//create derived objects
      l.push_back(d2);
      l.push_back(d2);
    
      for (list<spBase_t>::iterator i = l.begin(); i!= l.end(); i++)
      {
        ( (spDerived_t)(*i) )->print();
        //current->print();
      }
    }
    Se provo a sostituire banalmente le righe
    codice:
    typedef Base* spBase_t;
    typedef Derived* spDerived_t;
    con
    codice:
    typedef shared_ptr<Base> spBase_t;
    typedef shared_ptr<Derived> spDerived_t;
    il compilatore (gcc 4.2.) restituisce un errore del tipo:

    /usr/include/c++/4.2.1/tr1/boost_shared_ptr.h:562: error: invalid conversion from ‘Base* const’ to ‘Derived*’

    Grazie!

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Usa dynamic_pointer_cast<>
    codice:
      for (list<spBase_t>::iterator i = l.begin(); i!= l.end(); i++)
      {
        spDerived_t sd = dynamic_pointer_cast<Derived>(*i);
        sd->print();
      }
    Oppure

    codice:
      for (list<spBase_t>::iterator i = l.begin(); i!= l.end(); i++)
      {
           dynamic_pointer_cast<Derived>(*i)->print();
      }
    Se però il nuovo puntatore è nullo, hai un errore di accesso.

  3. #3
    Originariamente inviato da shodan
    Usa dynamic_pointer_cast<>
    codice:
      for (list<spBase_t>::iterator i = l.begin(); i!= l.end(); i++)
      {
        spDerived_t sd = dynamic_pointer_cast<Derived>(*i);
        sd->print();
      }
    Oppure

    codice:
      for (list<spBase_t>::iterator i = l.begin(); i!= l.end(); i++)
      {
           dynamic_pointer_cast<Derived>(*i)->print();
      }
    Se però il nuovo puntatore è nullo, hai un errore di accesso.
    Innanzitutto grazie della risposta.
    In realtà avevo già provato con il dynamic_pointer_cast, ma il compilatore mi restituisce

    /usr/include/c++/4.2.1/tr1/boost_shared_ptr.h:613: error: cannot dynamic_cast ‘__r->std::tr1::__shared_ptr<Base, _S_atomic>::_M_ptr’ (of type ‘class Base* const’) to type ‘class Derived*’ (source type is not polymorphic)

    Come puoi vedere non ho metodi polimorfici: potrei potenzialmente avere diverse classi derivate dalla medesima base ma con metodi molto diversi tra di loro.

    Il motivo per cui mi serve passare dalla medesima classe base è perché, in questo modo, potrei utilizzare il container 'list', dato che mi serve mantenere una lista di oggetti appartenenti a classi diverse. All'occorrenza, iterando su questa lista e riconoscendo il tipo di oggetto, effettuo il cast opportuno e lancio i diversi metodi secondo la logica del mio programma.

    Grazie

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    D'accordo, ma a questo punto tanto vale usare void* come tipo base ed effettuare degli static_cast appositi.
    Se utilizzi una classe base, devi almeno rendere virtuale il distruttore, altrimenti non vengono richiamati i distruttori delle classi derivate se si effettua il delete del puntatore base.
    codice:
    class Base {
        ~Base() {} // può essere vuoto.
    };
    
    // oppure
    class Base {
        ~Base()=0; // impone la derivazione forzata della classe.
    };
    
    Base::~Base() {} // se no il linker da errore.
    
    class Derivata1 : public Base {
    
    // dati per Derivata1
    
    };
    ...
    class DerivataN : public Base {
    
    // dati per DerivataN
    
    };

  5. #5
    Giusto, mi era sfuggito quest'ultimo punto.

    Grazie mille

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.