Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Star Wars Zero Company è l'erede di XCOM 2
Star Wars Zero Company è l'erede di XCOM 2
Bit Reactor porta nell’universo di Star Wars una struttura tattica che richiama apertamente XCOM 2, ma la arricchisce con legami tra i personaggi, progressione ruolistica, gestione della base e un sistema di combattimento costruito attorno a tre Punti Azione e alle risorse condivise della squadra
Test ride Can-Am Origin: la moto elettrica che fa dimenticare il motore a scoppio (ma occhio all'autonomia)
Test ride Can-Am Origin: la moto elettrica che fa dimenticare il motore a scoppio (ma occhio all'autonomia)
Abbiamo provato per una settimana intera la Can-Am Origin, la Dual Sport elettrica del gruppo canadese BRP: ecco com'è andata tra città, autostrada e un primo assaggio di sterrato
Logitech G325, G305 e G316 X: il tris per chi non vuole rinunciare a nulla, spendendo poco
Logitech G325, G305 e G316 X: il tris per chi non vuole rinunciare a nulla, spendendo poco
Nelle ultime settimane abbiamo provato il mouse Logitech G305, la tastiera G316 X 98 e le cuffie G325. Si tratta del setup entry-level di Logitech che ormai, di "entry-level" ha ben poco. Tastiera e mouse offrono prestazioni di livello competitivo con quasi nessuna rinuncia e un livello di personalizzazione estremamente elevato. Le cuffie, invece, hanno mostrato qualche debolezza, ma propongono un ventaglio di funzionalità completo che consente di abbandonare completamente i cavi
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 08-09-2014, 16: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, 17: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, 18: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, 18: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, 00: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, 06: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, 12: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, 15: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, 16: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, 16: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, 16: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, 17: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, 18: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, 18: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, 19: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, 18: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, 12: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


Star Wars Zero Company è l'erede di XCOM 2 Star Wars Zero Company è l'erede di XCOM ...
Test ride Can-Am Origin: la moto elettrica che fa dimenticare il motore a scoppio (ma occhio all'autonomia) Test ride Can-Am Origin: la moto elettrica che f...
Logitech G325, G305 e G316 X: il tris per chi non vuole rinunciare a nulla, spendendo poco Logitech G325, G305 e G316 X: il tris per chi no...
Recensione POCO F9 pro: potenza da vero top di gamma, display da 185 Hz e finalmente una fotocamera da prendere sul serio Recensione POCO F9 pro: potenza da vero top di g...
Tra audio e AI: la ricetta di Qualcomm per l'agentic AI Tra audio e AI: la ricetta di Qualcomm per l'age...
ESA e ClearSpace svilupperanno un satell...
Oracle, stock option da quasi un miliard...
Starship: si è conclusa anticipat...
Un computer quantistico ha funzionato ne...
Sovranità sui dati: AWS è ...
Il nuovo nome della distro Linux mobile ...
Due ventole da 220 mm e non solo: Cooler...
Truffa telefonica via Google Ads: il bro...
Google pensiona le Gems di Gemini: cosa ...
Flight 14: incertezza per un problema a ...
C'è un problema con i robot Tesla: i dip...
Raggi gamma anomali dalla Via Lattea sve...
NIO vende il 30% della divisione scambio...
Sony brevetta un DualSense capace di acc...
Un volto per l'assistenza IA: cosa pu&og...
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: 18:43.


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