Visualizzazione dei risultati da 1 a 10 su 17

Discussione: [C++] Classi

Hybrid View

  1. #1
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Il tuo codice (riportato qui) non compila nemmeno. Solo ora mi sono accorto che non esiste ereditarietà tra le classi, il rende la discussione falsata in partenza (hai riportato male il codice?)

    In caso di ereditarietà, molto meglio la seconda soluzione (pattern Strategy http://www.vincehuston.org/dp/strategy.html)

    Ancora meglio usando smart pointer (qui uso std::unique_ptr).

    Notare che quello che viene fatto nel main può essere a sua volta incapsulato in una classe secondo il pattern State:
    http://www.vincehuston.org/dp/state.html

    codice:
    int main()
    {
    
    std::unique_ptr<Sezione_type> sezione;
    ...
    //righe di codice che permettono di scegliere se sezione rettangolare o circolare e fare l'input dei dati come base e
    //altezza o in alternativa diametro
    ...
    //in base a quanto fatto prima se ho scelto sezione rettangolare
    sezione.reset(new Sezione_rettangolare_type(B,H));
    sezione->calcola_area();
    
    //in base al nuovo tipo di sezione scelta, rifaccio
    sezione.reset(new Sezione_circolare_type(D));
    sezione->calcola_area();
    
    return 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.

  2. #2
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Quote Originariamente inviata da shodan Visualizza il messaggio
    Il tuo codice (riportato qui) non compila nemmeno. Solo ora mi sono accorto che non esiste ereditarietà tra le classi, il rende la discussione falsata in partenza (hai riportato male il codice?)
    Per quanto riguarda il codice del primo mio intervento, non lo ho mai provato, per quanto riguarda il secondo, avevo accennato qualcosa
    Quote Originariamente inviata da ing82 Visualizza il messaggio
    Approfondendo la questione (=studiare), mi viene in mente che la mia situazione possa essere gestita in maniera forse più efficiente nel seguente modo (a parte il fatto di aver implementato le funzioni membro direttamente all'interno della classe, ma non ho a disposizione il codice che ho testato con la classica divisione nei file .h e . cpp)
    Grazie
    Sono andato a memoria di quanto avevo fatto...molto probabile che ci sia qualche strafalcione, però non capisco perchè dici
    Quote Originariamente inviata da shodan Visualizza il messaggio
    non esiste ereditarietà tra le classi
    ...oooops

    adesso, rileggendo meglio, direi proprio di si, dopo Sezione_rettangolare_type e Sezione_circolare_type ci andava un bel
    codice:
    class Sezione_rettangolare_type:public Sezione_type
    ...
    
    class Sezione_cicolare_type:public Sezione_type
    ...
    Per il resto, vado ad approfondire.

    Grazie

  3. #3
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Quote Originariamente inviata da shodan Visualizza il messaggio
    Ancora meglio usando smart pointer (qui uso std::unique_ptr).
    Ma quindi tendenzialmente, se ho dati membro di una classe dichiarati come puntatori, conviene definirli come smart pointer, così evito nel distruttore di dover richiamare il delete, corretto?

    codice:
    class Classe
    {
      public:
        //costruttore, ecc;
        //il distruttore è
        ~Classe(){delete(puntatore);/*altre eventuali cose*/};
      private:
        //quello che serve
        tipoDelPuntatore* puntatore;
    }
    diventa
    codice:
    class Classe
    {
      public:
        //costruttore, ecc;
        //il distruttore è
        ~Classe(){/*altre eventuali cose, ma delete(puntatore) non dovrebbe servire più*/};
      private:
        //quello che serve
        std::unique_ptr<tipoDelPuntatore> puntatore;
    }
    Ne approfitto per una ulteriore domanda: se il dato membro di tipo puntatore sarà usato solo "interno" alla classe, uso unique_ptr, se invece sarà impiegato anche da qualche altro oggetto, uso shared_ptr, corretto?

    Grazie, grazie, grazie

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Quote Originariamente inviata da ing82 Visualizza il messaggio
    Ma quindi tendenzialmente, se ho dati membro di una classe dichiarati come puntatori, conviene definirli come smart pointer, così evito nel distruttore di dover richiamare il delete, corretto?
    Tendenzialmente si, ma non c'è una regola fissa: occorre valutare quello che si vuole fare.
    Lo shared_ptr mantiene un contatore interno di quante volte è stato copiato e l'ultimo a uscire cancella il puntatore, MA la memoria condivisa è la stessa. Se devi fare una deep copy dell'oggetto puntato lo devi fare esplicitamente.

    codice:
        shared_ptr<int> p = new int(10); // contatore = 1
        shared_ptr<int> q = p; // contatore = 2
        *q = 20; 
        cout << *p << endl; // 20 perché il puntatore interno è condiviso tra p e q.
    
        shared_ptr<int> z = new int;
        *z = *q;
        *q = 30;
    
        cout << *z << endl; // 20 perché il puntatore interno di z non è condiviso con p e q.
        cout << *p << endl; // 30 perché il puntatore interno è condiviso tra p e q.
    Con unique_ptr la faccenda è molto più semplice: non può essere copiato.
    codice:
        unique_ptr<int> p(new int(10))
        unique_ptr<int> q = p; // errore: unique_ptr non può essere copiato
    
        unique_ptr<int> q = std:move(p); // ma può essere spostato.
        // cout << *p << endl;  crash: il puntatore interno di p ora è nullptr
        cout << *q << endl; // vale 10.
    
        unique_ptr<int> z (new int);
        *z = *q;
    Ne approfitto per una ulteriore domanda: se il dato membro di tipo puntatore sarà usato solo "interno" alla classe, uso unique_ptr, se invece sarà impiegato anche da qualche altro oggetto, uso shared_ptr, corretto?
    Non proprio: userari shared_ptr se la tua classe dev'essere copiabile, quindi condividere il dato interno con copie di classe uguale; userai unique_ptr se non vuoi che la tua classe sia copiabile e quindi non condividere il dato interno con copie di classe uguale.
    Ambedue i puntatori possono essere restituiti da funzioni, ma se restituisci uno shared_ptr avrai il dato interno esistente, se usi uno unique_ptr stai dicendo: "classe X non devi più occuparti della gestione di unique_ptr<dato> perché ci pensa qualcun altro.

    Spero di essermi spiegato.
    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 L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Quote Originariamente inviata da shodan Visualizza il messaggio
    Spero di essermi spiegato.
    Direi di sì. Il mio problema è la mancanza di esperienza, quindi dovrò ora fare qualche prova e capire con la pratica.
    Così a naso, direi che potrei partire usando unique_ptr (sempre riferito a dati membro di una classe) e quando mi accorgo che in realtà avrei fatto meglio ad usare shared_ptr, cambiare.

    Per ora grazie della disponibilità, ora faccio qualche prova.

  6. #6
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Prova n° 1

    codice:
    #include <iostream>
    #include <stdlib.h>
    #include <memory>
    
    using namespace std;
    
      class Prova
      {
        public:
          Prova(){cout<<"\nCreato l'oggetto Prova!";};
          ~Prova(){cout<<"\nDistrutto l'oggetto Prova!";};
          void run(){cout<<"\nProva is running!";};
          void pause(){cout<<"\nProva is paused!";};
          void termin(){cout<<"\nProva is terminated!";};
      };
    
      class Oggetto
      {
        public:
          Oggetto(){cout<<"\nCreato l'oggetto Oggetto!";};
          Oggetto(shared_ptr<Prova> puntatore):mProva(puntatore){cout<<"\nCreato l'oggetto Oggetto!";};
          ~Oggetto(){cout<<"\nDistrutto l'oggetto Oggetto!";};
          void run(){cout<<"\nOggetto is running!";mProva->run();};
          void pause(){cout<<"\nOggetto is paused!";mProva->pause();};
          void termin(){cout<<"\nOggetto is terminated!";mProva->termin();};
        private:
          shared_ptr<Prova> mProva;
      };
    
    int main()
    {
      {
        unique_ptr<Prova> prova(new Prova);
        prova->run();
        prova->pause();
        prova->run();
        prova->termin();
      }
      system("pause");
      return 0;
    }
    Al termine dell'esecuzione vedo che viene richiamato il distruttore di prova.
    Ultima modifica di ing82; 23-12-2015 a 23:31

  7. #7
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Prova n° 2

    codice:
    #include <iostream>
    #include <stdlib.h>
    #include <memory>
    
    using namespace std;
    
      class Prova
      {
        public:
          Prova(){cout<<"\nCreato l'oggetto Prova!";};
          ~Prova(){cout<<"\nDistrutto l'oggetto Prova!";};
          void run(){cout<<"\nProva is running!";};
          void pause(){cout<<"\nProva is paused!";};
          void termin(){cout<<"\nProva is terminated!";};
      };
    
      class Oggetto
      {
        public:
          Oggetto(){cout<<"\nCreato l'oggetto Oggetto!";};
          Oggetto(shared_ptr<Prova> puntatore):mProva(puntatore){cout<<"\nCreato l'oggetto Oggetto!";};
          ~Oggetto(){cout<<"\nDistrutto l'oggetto Oggetto!";};
          void run(){cout<<"\nOggetto is running!";mProva->run();};
          void pause(){cout<<"\nOggetto is paused!";mProva->pause();};
          void termin(){cout<<"\nOggetto is terminated!";mProva->termin();};
        private:
          shared_ptr<Prova> mProva;
      };
    
    int main()
    {
      {
        shared_ptr<Prova> prova(new Prova);
        prova->run();
        prova->pause();
        prova->run();
        prova->termin();
        system("pause");
        {
          unique_ptr<Oggetto> oggetto(new Oggetto(prova));
          oggetto->run();
          oggetto->pause();
          oggetto->run();
          oggetto->termin();
        }
        system("pause");
      }
      system("pause");
      return 0;
    }
    E così vedo che ad ogni fuori scope viene richiamato il distruttore corretto.

  8. #8
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Prova n° 3

    codice:
    #include <iostream>
    #include <stdlib.h>
    #include <memory>
    
    using namespace std;
    
      class Prova
      {
        public:
          Prova(){cout<<"\nCreato l'oggetto Prova!";};
          ~Prova(){cout<<"\nDistrutto l'oggetto Prova!";};
          void run(){cout<<"\nProva is running!";};
          void pause(){cout<<"\nProva is paused!";};
          void termin(){cout<<"\nProva is terminated!";};
      };
    
      class Oggetto
      {
        public:
          Oggetto(){cout<<"\nCreato l'oggetto Oggetto!";};
          Oggetto(shared_ptr<Prova> puntatore):mProva(puntatore){cout<<"\nCreato l'oggetto Oggetto!";};
          ~Oggetto(){cout<<"\nDistrutto l'oggetto Oggetto!";};
          void run(){cout<<"\nOggetto is running!";mProva->run();};
          void pause(){cout<<"\nOggetto is paused!";mProva->pause();};
          void termin(){cout<<"\nOggetto is terminated!";mProva->termin();};
        private:
          shared_ptr<Prova> mProva;
      };
    
    int main()
    {
      {
        shared_ptr<Prova> prova(new Prova);
        prova->run();
        prova->pause();
        prova->run();
        prova->termin();
        system("pause");
        {
          unique_ptr<Oggetto> oggetto(new Oggetto(prova));
          oggetto->run();
          oggetto->pause();
          oggetto->run();
          oggetto->termin();
          prova.reset();
          oggetto->run();
        }
        system("pause");
      }
      system("pause");
      return 0;
    }
    In questo modo vedo che dopo il reset, l'area puntata tramite prova, è comunque accessibile, perchè "shared" con oggetto, e alla prima chiusura di parentesi, vengono chiamati entrambi i distruttori.

    Restano da studiare i weak_ptr, ma buone vacanze.

    Auguri di un buon S. Natale a tutti!

  9. #9
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Quote Originariamente inviata da shodan Visualizza il messaggio
    In caso di ereditarietà, molto meglio la seconda soluzione (pattern Strategy http://www.vincehuston.org/dp/strategy.html)

    ......

    Notare che quello che viene fatto nel main può essere a sua volta incapsulato in una classe secondo il pattern State:
    http://www.vincehuston.org/dp/state.html
    A suo tempo, quando avevo guardato i due link, non ne avevo capito l'importanza: in inglese, senza codici di esempio, li avevo lasciati perdere...

    Solo ora ho capito che fanno parte del "Design Patterns", mondo a me sconosciuto!

    Per gli ignoranti come me, forse anche questo link può dare una mano a capire l'argomento, c'è qualche riga di codice di esempio.

    Grazie infinite ancora Shodan, ma non avevo compreso l'aiuto fornito...ora sotto con lo studio

    (e poi tornerò alla ribalta con tutti i miei dubbi)

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