Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Sistema Mesh Roamii BE Pro: il Wi-Fi 7 secondo MSI
Sistema Mesh Roamii BE Pro: il Wi-Fi 7 secondo MSI
Con velocità teoriche fino a 11 Gbps, gestione tramite app intelligente e protezione avanzata dei dispositivi, Roamii BE Pro porta il Wi‑Fi 7 tri‑band nelle abitazioni più esigenti. Un sistema Wi-Fi Mesh proposto da MSI allo scopo di garantire agli utenti una rete fluida e continua capace di sostenere streaming 8K, gaming competitivo e le applicazioni moderne più esigenti in termini di banda
Recensione HUAWEI Mate X7: un foldable ottimo, ma restano i soliti problemi
Recensione HUAWEI Mate X7: un foldable ottimo, ma restano i soliti problemi
Mate X7 rinnova la sfida nel segmento dei pieghevoli premium puntando su un design ancora più sottile e resistente, unito al ritorno dei processori proprietari della serie Kirin. L'assenza dei servizi Google e del 5G pesa ancora sull'esperienza utente, ma il comparto fotografico e la qualità costruttiva cercano di compensare queste mancanze strutturali con soluzioni ingegneristiche di altissimo livello
Nioh 3: souls-like punitivo e Action RPG
Nioh 3: souls-like punitivo e Action RPG
Nioh 3 aggiorna la formula Team NINJA con aree esplorabili più grandi, due stili di combattimento intercambiabili al volo (Samurai e Ninja) e un sistema di progressione pieno di attività, basi nemiche e sfide legate al Crogiolo. La recensione entra nel dettaglio su combattimento, build, progressione e requisiti PC
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 08-09-2014, 17:30   #1
mistergks
Senior Member
 
L'Avatar di mistergks
 
Iscritto dal: Mar 2011
Messaggi: 1050
[c++] oggetti classe astratta

Sto cercando di capire delle cose.
Ho una classe astratta (classe base) con metodi virtuali puri.

Poi ho una seconda classe (classe figlia.. Con metodi NON virtuali puri) che eredita la classe astratta.

So che non si possono istanziare oggetti di una classe astratta.

Le mie domande sono:
1) posso istanziare un puntatore a un oggetto?
2)posso istanziare un oggetto se definisco tutti i metodi virtuali puri della classe astratta?
mistergks è offline   Rispondi citando il messaggio o parte di esso
Old 08-09-2014, 18:52   #2
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
Quote:
Originariamente inviato da mistergks Guarda i messaggi
Sto cercando di capire delle cose.
Ho una classe astratta (classe base) con metodi virtuali puri.

Poi ho una seconda classe (classe figlia.. Con metodi NON virtuali puri) che eredita la classe astratta.

So che non si possono istanziare oggetti di una classe astratta.

Le mie domande sono:
1) posso istanziare un puntatore a un oggetto?
2)posso istanziare un oggetto se definisco tutti i metodi virtuali puri della classe astratta?
Sono tutte semplici domande che avresti potuto rispondere da solo facendo un esempietto da 10 linee Ti consiglio di farlo in futuro, ti salva un sacco di tempo che chiedere sul forum.

Detto questo:

1) Un puntatore e' sempre instanziabile, perche' e' uno dei tipi primitivi. Il poter instanziare puntatori a classi base astratte e' una delle caratteristiche fondamentali su cui si basa l' OOP in C++.

2) Ovviamente si Devi ereditare la classe base e definire i metodi virtuali che non sono stati implementati nella classe base. Se li definisci tutti la classe derivata non e' più astratta ed e' normalmente istanziabile.

Ciao
__________________
GPU Compiler Engineer
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 08-09-2014, 19:06   #3
Freaxxx
Senior Member
 
L'Avatar di Freaxxx
 
Iscritto dal: Dec 2006
Messaggi: 3808
puoi usare dei nomi in maiuscolo per le classi e in minuscolo per i metodi/funzioni membri delle classi ?

Comunque come regola generale non puoi instanziare nessun tipo che sia incompleto ma puoi avere un puntatore ad un tipo incompleto .

Va da se che se non puoi instanziare un tipo incompleto, dereferenziare un puntatore ad un tipo incompleto non è una operazione permessa e anche se ci provi dovresti ottenere un errore in fase di compilazione .

Per quanto riguarda le funzioni/metodi virtual è una questione di design e convenienza relativa all'ereditarietà e a quanto ti conviene riusare il codice di 1 classe in più sottoclassi, è un modo per scrivere meno codice e/o ottenere un certo comportamento dai tipi .

Il punto è semplice, se non definisci tutte le funzioni che sono marcate come pure virtual nel tipo X non puoi istanziare quel tipo, e quel tipo ti serve solo come base dalla quale partire per costruire tutte le sotto-classi del tipo X, ovvero classi che ereditano da X .

Questo è qualcosa di molto simile rispetto a quanto accade in C con tipi struct incompleti, in C++ una classe astratta ( nota che in C++ non esistono classi astratte in sé per sé, come qualcosa di definito da una keyword, "classe astratta" è più un retaggio proveniente da Java, in C++ esistono tipi incompleti e metodi virtual/pure virtual, comunque tutti i programmatori C++ sanno cos'è una "classe astratta" in C++ ), alla fine si tratta sempre di tipi incompleti, per completare un tipo ti servono sempre 2 componenti ben definite: la parte relativa alle variabili di istanza e la parte relativa ai metodi/funzioni, i membri del tuo tipo, se queste 2 parti sono ben definite secondo il linguaggio il tuo compilatore saprà cosa farci, altrimenti puoi al massimo creare puntatori e/o riferimenti e il tuo tipo non avrà più valore di una semplice tag, di un semplice nome .
Freaxxx è offline   Rispondi citando il messaggio o parte di esso
Old 08-09-2014, 19:16   #4
Freaxxx
Senior Member
 
L'Avatar di Freaxxx
 
Iscritto dal: Dec 2006
Messaggi: 3808
Quote:
Originariamente inviato da AnonimoVeneziano Guarda i messaggi
Sono tutte semplici domande che avresti potuto rispondere da solo facendo un esempietto da 10 linee Ti consiglio di farlo in futuro, ti salva un sacco di tempo che chiedere sul forum.

Detto questo:

1) Un puntatore e' sempre instanziabile, perche' e' uno dei tipi primitivi. Il poter instanziare puntatori a classi base astratte e' una delle caratteristiche fondamentali su cui si basa l' OOP in C++.

2) Ovviamente si Devi ereditare la classe base e definire i metodi virtuali che non sono stati implementati nella classe base. Se li definisci tutti la classe derivata non e' più astratta ed e' normalmente istanziabile.

Ciao
ma anche no.

la ragione per la quale si può instanziare un puntatore ad un tipo incompleto è che anche non disponendo della definizione del tipo, e quindi non sapendo il "layout" e la dimensione del tipo, la dimensione di un puntatore è definita dall'ambiente che usi, ergo è possibile costruire ed instanziare una variabile che sia espressione relativa a T*; dereferenziare quello a cui punta T* sarà un altro paio di maniche, ma intanto il puntatore T* lo puoi creare semplicemente perché non ti serve praticamente nessuna informazione su T per creare T* .

tu adesso potresti scrivere il codice che ti pare, quanti tipi incompleti ti pare e piace, ma se sei sotto un ambiente a 32 bit, con tutta probabilità il tuo T* t; sarà definibile come una variabile da 32 bit / 4 byte ( 1 byte = 8 bit ) o se sei sotto un ambiente 64 bit t sarà una variabile da ben 8 byte .
Freaxxx è offline   Rispondi citando il messaggio o parte di esso
Old 09-09-2014, 01:07   #5
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da Freaxxx Guarda i messaggi
ma anche no.

la ragione per la quale si può instanziare un puntatore ad un tipo incompleto è che anche non disponendo della definizione del tipo, e quindi non sapendo il "layout" e la dimensione del tipo, la dimensione di un puntatore è definita dall'ambiente che usi, ergo è possibile costruire ed instanziare una variabile che sia espressione relativa a T*; dereferenziare quello a cui punta T* sarà un altro paio di maniche, ma intanto il puntatore T* lo puoi creare semplicemente perché non ti serve praticamente nessuna informazione su T per creare T* .

tu adesso potresti scrivere il codice che ti pare, quanti tipi incompleti ti pare e piace, ma se sei sotto un ambiente a 32 bit, con tutta probabilità il tuo T* t; sarà definibile come una variabile da 32 bit / 4 byte ( 1 byte = 8 bit ) o se sei sotto un ambiente 64 bit t sarà una variabile da ben 8 byte .
Beh non mi pare che la risposta di Anonimo sia sbagliata... Il compilatore conosce i tipi primitivi, quelli user-defined dobbiamo "spiegarglieli" noi. Ergo un tipo primitivo non è mai incompleto per definizione. Ergo un tipo primitivo è sempre istanziabile...
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 09-09-2014, 07:51   #6
Freaxxx
Senior Member
 
L'Avatar di Freaxxx
 
Iscritto dal: Dec 2006
Messaggi: 3808
Quote:
Originariamente inviato da vendettaaaaa Guarda i messaggi
Beh non mi pare che la risposta di Anonimo sia sbagliata... Il compilatore conosce i tipi primitivi, quelli user-defined dobbiamo "spiegarglieli" noi. Ergo un tipo primitivo non è mai incompleto per definizione. Ergo un tipo primitivo è sempre istanziabile...
sarà pure corretta ma mi sembra molto sui generis, è anche vero che potresti considerare un puntatore come un tipo a sé, ma poi devi spiegare e illustrare perché non puoi dereferenziare un puntatore anche se è possibile dichiararlo .
Freaxxx è offline   Rispondi citando il messaggio o parte di esso
Old 09-09-2014, 13:31   #7
mistergks
Senior Member
 
L'Avatar di mistergks
 
Iscritto dal: Mar 2011
Messaggi: 1050
Quote:
Originariamente inviato da AnonimoVeneziano Guarda i messaggi
2) Ovviamente si Devi ereditare la classe base e definire i metodi virtuali che non sono stati implementati nella classe base. Se li definisci tutti la classe derivata non e' più astratta ed e' normalmente istanziabile.

E se li definisco tutti i metodi virtuali puri della classe base all'interno della classe derivata.. Anche la classe base diventa una classe concreta o rimane astratta e quindi non istanziabile?
mistergks è offline   Rispondi citando il messaggio o parte di esso
Old 09-09-2014, 16:18   #8
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
Quote:
Originariamente inviato da mistergks Guarda i messaggi
E se li definisco tutti i metodi virtuali puri della classe base all'interno della classe derivata.. Anche la classe base diventa una classe concreta o rimane astratta e quindi non istanziabile?
La definizione della classe base e' del tutto indipendente dalla definizione delle classi derivate. La classe base rimane e rimarrà sempre astratta a meno che non la cambi tu direttamente dandogli delle implementazioni di default.
__________________
GPU Compiler Engineer
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 09-09-2014, 17:02   #9
mistergks
Senior Member
 
L'Avatar di mistergks
 
Iscritto dal: Mar 2011
Messaggi: 1050
E quindi non posso istanziare oggetti della classe base pur definendo tutti i metodi virtuali puri della classe base all'interno della classe derivata?
mistergks è offline   Rispondi citando il messaggio o parte di esso
Old 09-09-2014, 17:10   #10
Freaxxx
Senior Member
 
L'Avatar di Freaxxx
 
Iscritto dal: Dec 2006
Messaggi: 3808
Quote:
Originariamente inviato da mistergks Guarda i messaggi
E quindi non posso istanziare oggetti della classe base pur definendo tutti i metodi virtuali puri della classe base all'interno della classe derivata?
Yes, l'ereditarietà di una classe astratta serve solo a te in qualità di programmatore, per quanto riguarda il linguaggio si tratta di un tipo incompleto .
Freaxxx è offline   Rispondi citando il messaggio o parte di esso
Old 09-09-2014, 17:31   #11
mistergks
Senior Member
 
L'Avatar di mistergks
 
Iscritto dal: Mar 2011
Messaggi: 1050
Nemmeno un puntatore alla classe base?
mistergks è offline   Rispondi citando il messaggio o parte di esso
Old 09-09-2014, 18:10   #12
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
Quote:
Originariamente inviato da mistergks Guarda i messaggi
Nemmeno un puntatore alla classe base?
Il puntatore di una classe puo' essere sempre creato e usato , anche per riferirsi alle classi derivate.

Per esempio se hai :
Codice:
class A { // Classe astratta };
class B : public A { // Classe NON astratta };
Puoi fare:
Codice:
A *ptr = new B();
ptr->metodo(); // Metodo deve essere definito in A (pure virtual o no)
Non potrai mai fare invece:
Codice:
A *ptr = new A();
A obj;
o qualsiasi altro codice che instanzi direttamente A.

La classe "A" serve solo per definire una interfaccia da usare poi istanziando una
qualche classe derivata.

Ti consiglio di prenderti un libro e di leggerti/rileggerti il capitolo su ereditarieta' e polimorfismo, perche' sembra che tu non abbia capito a cosa serve l'esistenza delle classi astratte
Vedrai che dopo tutto prendera' immediatamente senso.

Ciao
__________________
GPU Compiler Engineer
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 09-09-2014, 19:17   #13
mistergks
Senior Member
 
L'Avatar di mistergks
 
Iscritto dal: Mar 2011
Messaggi: 1050
E posso fare questo?:
list<A>

E questo?
list<A *>
mistergks è offline   Rispondi citando il messaggio o parte di esso
Old 09-09-2014, 19:28   #14
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da mistergks Guarda i messaggi
E posso fare questo?:
list<A>

E questo?
list<A *>
No, sì.
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 09-09-2014, 20:12   #15
mistergks
Senior Member
 
L'Avatar di mistergks
 
Iscritto dal: Mar 2011
Messaggi: 1050
[c++] oggetti classe astratta

L'istanziazione qui invece è corretta?? Parlo dell'oggetto "Rifiuto"

Codice:
class GestoreOrdineRifiuti : protected list
{
	public:
		GestoreOrdineRifiuti();
		Rifiuto* pop();
		unsigned size() const;
		void push (Rifiuto* r)
		{
			list::iterator it = begin();
			while ( it!= end() && *r < *(*it) )
				it++;
			insert (it, r );
		}
};


void SistemaSmaltimento::smaltisciTutti( const GestoreOrdineRiifuti& gestore)
{
	while (gestore.size() > 0 )
	{
		Rifiuto* r = gestore.pop();
		r->smaltisci(this);
		delete (r);
	}
}


Svolgimento
progettare utilizzando l&rsquo;ereditarietà e il polimorfismo, le interfacce ( solo file di intestazione ) della classe Rifiuto e di almeno due classi che modellano particolari riifuti

enum Tipo {  Organico = 0 , Allumino, Plastica  };
class Rifiuto
{
	public:
		Rifiuto ( Tipo, string, string );
		virtual ~Rifiuto( );
		virtual string getProvenienza( ) const = 0;
		virtual string getDestinazione ( ) const = 0;
		virtual Tipo getTipo( ) const  = 0;
		virtual void smaltisci(SistemaSmaltimento* ) const = 0;

		
	protected:
		Tipo tipo;
		string provenienza;
		string destinazione;
};

class Organico : public Rifiuto
{
	protected:
		int quantità;
		string data;

	public:
		Organico( );
		~Organico( );

		void setQuantita( int );
		void setData ( string );
		
		virtual string getProvenienza( ) const { return provenienza };
		virtual string getDestinazione ( ) const { return destinazione };
		virtual Tipo getTipo ( ) const { return tipo };
		virtual void smaltisci ( SistemaSmaltimento*);
};

//la classe Allmumino sarà uguale


implementare tutti i metodi lasciati incompleti nella classe GestoreOrdineRifiuti

//costruttore GestoreOrdineRifiuti( ), di default perché non ci sono campi da settare
GestoreOrdineRifiuti::GestoreOrdineRifiuti( ) {}


//funzione pop( )
Rifiuto* GestoreOrdineRifiuti::pop( )
{
	Rifiuto rifiuto = back( );
	pop_back( );
	return rifiuto;
}

//funzione size( )
unsigned GestoreOrdineRifiuti::size( )
{
	return list.size( );
}
mistergks è offline   Rispondi citando il messaggio o parte di esso
Old 12-09-2014, 19:00   #16
mistergks
Senior Member
 
L'Avatar di mistergks
 
Iscritto dal: Mar 2011
Messaggi: 1050
Up
mistergks è offline   Rispondi citando il messaggio o parte di esso
Old 15-09-2014, 13:58   #17
tomminno
Senior Member
 
Iscritto dal: Oct 2005
Messaggi: 3306
Se non sbaglio il tuo codice non istanzia mai un oggetto di un tipo derivato da Rifiuto, quindi è difficile risponderti

Il codice ha un po' di problemi: dichiari che GestoreOrdineRifiuti estende list
ma nel metodo size restituisci list.size(), il compilatore dovrebbe darti errore, chi è list?

Al metodo pop gli manca un puntatore. Da questo metodo mi pare di capire che list non sia std::list, ma una tua implementazione giusto? Altrimenti dovresti rivedere il design in quanto è male derivare dai container standard non avendo questi il distruttore virtuale.

Nota di colore:
Codice:
r->smaltisci(this);
Il rifiuto smaltisce il sistema di smaltimento dei rifiuti?
tomminno è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Sistema Mesh Roamii BE Pro: il Wi-Fi 7 secondo MSI Sistema Mesh Roamii BE Pro: il Wi-Fi 7 secondo M...
Recensione HUAWEI Mate X7: un foldable ottimo, ma restano i soliti problemi Recensione HUAWEI Mate X7: un foldable ottimo, m...
Nioh 3: souls-like punitivo e Action RPG Nioh 3: souls-like punitivo e Action RPG
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti Test in super anteprima di Navimow i220 LiDAR: i...
Dark Perk Ergo e Sym provati tra wireless, software via browser e peso ridotto Dark Perk Ergo e Sym provati tra wireless, softw...
Project Panama: ecco come Anthropic ha d...
MrBeast entra nel fintech: Beast Industr...
Arrivano i nuovi server Bare Metal 2026 ...
Stop alla distribuzione dei driver di st...
Serie TV God of War: scelto anche l'atto...
Riot Games dimezza il team di 2XKO dopo ...
FRITZ! in super offerta su Amazon: ripet...
L'AI doveva farci lavorare meno: e se st...
DREAME X50 Ultra Complete a 899€ su Amaz...
Rimodulazione TIM: aumenti fino a 2,99 e...
Amazon sblocca i prezzi con coupon e sco...
Action cam Insta360 in super offerta su ...
Fallout 76 Sorgenti Brucianti: tanta car...
Scope elettriche super potenti a confron...
Tutti i Google Pixel 10 sono scontati su...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 13:31.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v