Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando
Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando
Abbiamo giocato a lungo a Battlefield 6, abbiamo provato tutte le modalità multiplayer, Redsec, e le numerose personalizzazioni. In sintesi, ci siamo concentrati su ogni aspetto del titolo per comprendere al meglio uno degli FPS più ambiziosi della storia dei videogiochi e, dopo quasi due mesi, abbiamo tirato le somme. In questo articolo, condividiamo con voi tutto ciò che è Battlefield 6, un gioco che, a nostro avviso, rappresenta esattamente ciò che questo genere attendeva da tempo
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare
Abbiamo messo alla prova il drone Antigravity A1 capace di riprese in 8K a 360° che permette un reframe in post-produzione ad eliche ferme. Il concetto è molto valido, permette al pilota di concentrarsi sul volo e le manovre in tutta sicurezza e decidere con tutta tranquillità come gestire le riprese. La qualità dei video, tuttavia, ha bisogno di uno step in più per essere competitiva
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator
Dopo oltre 4 anni si rinnova la serie Sony Alpha 7 con la quinta generazione, che porta in dote veramente tante novità a partire dai 30fps e dal nuovo sensore partially stacked da 33Mpixel. L'abbiamo provata per un breve periodo, ecco come è andata dopo averla messa alle strette.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 26-11-2012, 19:17   #1
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
[C++] Chiamare costruttore da un altro costruttore

Ciao,
ho cercato un po' in rete come chiamare un costruttore da un altro, della stessa classe ovviamente. Quasi tutti dicono che non si può:
Codice:
class Foo
{
public:
Foo() { /* do stuff */}
Foo(int x) : Foo() { m_x = x; } // NON COMPILA
Foo(int x)
{
Foo();     // NON COMPILA
m_x = x;
}
Foo(int x)
{
this->Foo();     // NON COMPILA
m_x = x;
}
private:
int m_x;
};
Poi è arrivato un tizio dicendo che
Codice:
Foo(int x)
{
this->Foo::Foo(); // COMPILA
m_x = x;
}
compila in Visual Studio di Microsoft. Ho provato e...funziona! Così mi risparmio di trasferire il codice comune ai miei due costruttori in una funzione di servizio privata.
Ma perchè in VS funziona così e non in altri compilatori? Ok, non sarà standard C++, ma mi pare una bella "customizzazione" da avere.
E poi perchè devo specificare la classe se uso this? Cioè scrivere this->Foo::Foo() anzichè solo this->Foo() ?
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 26-11-2012, 20:01   #2
L4ky
Senior Member
 
L'Avatar di L4ky
 
Iscritto dal: May 2008
Messaggi: 1566
Quote:
Originariamente inviato da vendettaaaaa Guarda i messaggi
Ciao,
ho cercato un po' in rete come chiamare un costruttore da un altro, della stessa classe ovviamente. Quasi tutti dicono che non si può:
Codice:
class Foo
{
public:
Foo() { /* do stuff */}
Foo(int x) : Foo() { m_x = x; } // NON COMPILA
Foo(int x)
{
Foo();     // NON COMPILA
m_x = x;
}
Foo(int x)
{
this->Foo();     // NON COMPILA
m_x = x;
}
private:
int m_x;
};
Poi è arrivato un tizio dicendo che
Codice:
Foo(int x)
{
this->Foo::Foo(); // COMPILA
m_x = x;
}
compila in Visual Studio di Microsoft. Ho provato e...funziona! Così mi risparmio di trasferire il codice comune ai miei due costruttori in una funzione di servizio privata.
Ma perchè in VS funziona così e non in altri compilatori? Ok, non sarà standard C++, ma mi pare una bella "customizzazione" da avere.
E poi perchè devo specificare la classe se uso this? Cioè scrivere this->Foo::Foo() anzichè solo this->Foo() ?
Se tu hai una classe x e vuoi chiamare una qualsiasi funzione della classe y, devi per forza fare
Quote:
y::funzione_della_classe_y();
Ora però non so dirti perché ti si presenti quel problema..
__________________
CM Obsidian 750D - Corsair TX650M - AMD Ryzen 7 3700x - Asus TUF B550-PLUS - nVidia Gigabyte GTX 1060 6GB G1 Gaming - Noctua D15S - Corsair Vengeance Pro 3600MHz 16GB - 2xHP x27i - Razer Deathadder - Logitech G15 v1 nVidia Edition- Roccat Taito King-Size - Fastweb (2011) | Alice(2015) | Alice(2016) | Eolo 30Mb (2016) | Wind3 4G Flat (2019) | PF AIR 100 (2021)
L4ky è offline   Rispondi citando il messaggio o parte di esso
Old 26-11-2012, 20:10   #3
msangi
Member
 
Iscritto dal: Sep 2011
Città: Londra
Messaggi: 167
Dai un'occhiata qui
__________________
Twitter - Blog
msangi è offline   Rispondi citando il messaggio o parte di esso
Old 26-11-2012, 21:29   #4
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da msangi Guarda i messaggi
Dai un'occhiata qui
Ho scritto questo post dopo aver letto proprio questa discussione

@L4ky: ma io voglio chiamare il costruttore della classe x dalla classe x!! Cioè, quando l'utente chiama il costruttore con 4 argomenti prima viene eseguito il costruttore con 1 argomento (che fa determinate cose) ed in più opera sugli altri 3 argomenti passati. Così da evitare di riscrivere, all'inizio del costruttore con 4 argomenti, il codice che già è scritto nel costruttore con 1 argomento:
Codice:
Species::Species(const char* fileName) : isTDStateDefined(false)
{
	ifstream ifs(fileName);
	if (!ifs) cerr << "Coudln't open file " << fileName << " - Cannot read species!" << endl;

	ifs >> name >> MW;
	ifs >> Tc >> Pc >> pitzer;
	ifs >> cp1 >> cp2 >> cp3 >> cp4 >> cp5 >> minCpT >> maxCpT;
	ifs >> hv1 >> hv2 >> hv3 >> hv4 >> minHvT >> maxHvT;
	ifs >> pv1 >> pv2 >> pv3 >> pv4 >> pv5 >> minPvT >> maxPvT;

	ifs.close();
}

Species::Species(const char* fileName, const double& T, const double& P, IEoS tipo)
{
	this->Species::Species(fileName);

	assign_TD_state(T, P, tipo);
}
Così facendo funziona, ma perchè devo specificare la classe all'interno della classe stessa?
Inoltre, lasciando perdere la formattazione poco robusta del file di input, so che sarebbe meglio delegare il compito del primo costruttore ad una funzione dedicata, tipo read_species_data(), sarebbe più giusto distinguere i compiti, ma mi sono incapponito su questo modo di operare per pura curiosità.

Ultima modifica di vendettaaaaa : 26-11-2012 alle 21:34.
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 26-11-2012, 22:33   #5
lorenzo001
Senior Member
 
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
Semplicemente così

Codice:
#include <iostream>

using namespace std;

class Foo
{
public:
	Foo() { cout << "Costr. 1" << endl;}
	
	Foo(int x)
	{
		cout << "Costr. 2" << endl;
		Foo();     
		m_x = x;
	}
	
private:
	int m_x;
};

int _tmain(int argc, _TCHAR* argv[])
{
	Foo f(0);

	return 0;
}
funziona con Visual C++ 2010 e DevC++ (mingw)

Ultima modifica di lorenzo001 : 26-11-2012 alle 22:37.
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
Old 26-11-2012, 22:51   #6
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da lorenzo001 Guarda i messaggi
Semplicemente così

Codice:
#include <iostream>

using namespace std;

class Foo
{
public:
	Foo() { cout << "Costr. 1" << endl;}
	
	Foo(int x)
	{
		cout << "Costr. 2" << endl;
		Foo();     
		m_x = x;
	}
	
private:
	int m_x;
};

int _tmain(int argc, _TCHAR* argv[])
{
	Foo f(0);

	return 0;
}
funziona con Visual C++ 2010 e DevC++ (mingw)
Hmm allora o ho un lapsus tremendo o qualcosa non va...potrebbe essere il lapsus
http://sdrv.ms/WT6ZLr
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 26-11-2012, 23:08   #7
lorenzo001
Senior Member
 
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
Manca la dichiarazione della classe per controllare ... comunque ti manca il costruttore di default ... aggiungi

Species() {};
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
Old 26-11-2012, 23:35   #8
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da lorenzo001 Guarda i messaggi
Manca la dichiarazione della classe per controllare ... comunque ti manca il costruttore di default ... aggiungi

Species() {};
Sì mi dice che manca quello di default ma non serve, infatti se uso la riga commentata (line 34, this-> eccetera) funziona.
http://sdrv.ms/QHkLPN
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 27-11-2012, 00:14   #9
lorenzo001
Senior Member
 
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
Non ho capito ... vedo che hai ancora i due errori ...
lorenzo001 è offline   Rispondi citando il messaggio o parte di esso
Old 27-11-2012, 00:31   #10
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da lorenzo001 Guarda i messaggi
Non ho capito ... vedo che hai ancora i due errori ...
E' la build di prima, stessi errori, t'ho postato l'.h della classe, come m'hai chiesto.
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 27-11-2012, 08:54   #11
tomminno
Senior Member
 
Iscritto dal: Oct 2005
Messaggi: 3306
Chiamare un costruttore da un altro costruttore (delegated constructors/forwarding constructors) è stato introdotto dal C++11 e questa funzionalità non è al momento supportata da Visual Studio 2012.
tomminno è offline   Rispondi citando il messaggio o parte di esso
Old 27-11-2012, 09:03   #12
tomminno
Senior Member
 
Iscritto dal: Oct 2005
Messaggi: 3306
Quote:
Originariamente inviato da lorenzo001 Guarda i messaggi
Semplicemente così

Codice:
#include <iostream>

using namespace std;

class Foo
{
public:
	Foo() { cout << "Costr. 1" << endl;}
	
	Foo(int x)
	{
		cout << "Costr. 2" << endl;
		Foo();     
		m_x = x;
	}
	
private:
	int m_x;
};

int _tmain(int argc, _TCHAR* argv[])
{
	Foo f(0);

	return 0;
}
funziona con Visual C++ 2010 e DevC++ (mingw)
Ehm qui stai semplicemente creando un oggetto di tipo Foo all'interno del costruttore Foo(int x), non stai chiamando il costruttore senza parametri per inizializzare l'oggetto...

Se non sei convinto prova così:
Codice:
class Foo
{
public:
	Foo() 
	{ 
		m_x = 4; 
		cout << "Costr. 1" << endl;  
		cout << m_x << endl;  
	}
	
	Foo(int x)
	{
		cout << "Costr. 2" << endl;
		m_x = x;
		Foo();    
		cout << m_x << endl;  
	}
	
private:
	int m_x;
};
tomminno è offline   Rispondi citando il messaggio o parte di esso
Old 27-11-2012, 13:23   #13
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da tomminno Guarda i messaggi
Ehm qui stai semplicemente creando un oggetto di tipo Foo all'interno del costruttore Foo(int x), non stai chiamando il costruttore senza parametri per inizializzare l'oggetto...

Se non sei convinto prova così:
Codice:
class Foo
{
public:
	Foo() 
	{ 
		m_x = 4; 
		cout << "Costr. 1" << endl;  
		cout << m_x << endl;  
	}
	
	Foo(int x)
	{
		cout << "Costr. 2" << endl;
		m_x = x;
		Foo();    
		cout << m_x << endl;  
	}
	
private:
	int m_x;
};
Vero, infatti così facendo (modifica in grassetto) invece funziona come dico io:
Codice:
#include <iostream>

using namespace std;

class Foo
{
public:
	Foo() 
	{ 
		m_x = 4; 
		cout << "Costr. 1" << endl;  
		cout << m_x << endl;  
	}
	
	Foo(int x)
	{
		cout << "Costr. 2" << endl;
		m_x = x;
		this->Foo::Foo();    
		cout << m_x << endl;  
	}
	
private:
	int m_x;
};

int main()
{
	Foo a(5);

	return 0;
}
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 28-11-2012, 11:56   #14
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da vendettaaaaa Guarda i messaggi
Vero, infatti così facendo (modifica in grassetto) invece funziona come dico io:
quel che stai facendo e' molto pericoloso
Considera i seguenti
- Il costruttore inizializza inizializza tutti i campi di un oggetto.
- Alcuni campi potrebbero avere tipo con costruttore non banale (ad esempio, alloco memoria)
- Non viene mai chiamato il corrispondente distruttore del primo costruttore.


Esempio
Codice:
struct Foo
{
   int* mem;

   Foo()
   {
      mem = new int;
   }

   ~Foo()
   {
      delete mem;
   }
};



struct Bar
{
   Foo foo;

   Bar(){ *foo->mem = 0; }

   Bar(int x)     
   {
       this->Bar::Bar();
       *foo->mem = x;
   }
};

void baz()
{
  Bar bar;
}
Domanda: all'uscita da baz quanta memoria ho allocato dinamicamente ? Quanta ne ho liberata ?
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 28-11-2012, 12:09   #15
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da marco.r Guarda i messaggi
quel che stai facendo e' molto pericoloso
Considera i seguenti
- Il costruttore inizializza inizializza tutti i campi di un oggetto.
- Alcuni campi potrebbero avere tipo con costruttore non banale (ad esempio, alloco memoria)
- Non viene mai chiamato il corrispondente distruttore del primo costruttore.


Esempio
Codice:
struct Foo
{
   int* mem;

   Foo()
   {
      mem = new int;
   }

   ~Foo()
   {
      delete mem;
   }
};



struct Bar
{
   Foo foo;

   Bar(){ *foo->mem = 0; }

   Bar(int x)     
   {
       this->Bar::Bar();
       *foo->mem = x;
   }
};

void baz()
{
  Bar bar;
}
Domanda: all'uscita da baz quanta memoria ho allocato dinamicamente ? Quanta ne ho liberata ?
Ma non c'è qualcosa di sbagliato? Foo foo non è un puntatore, perchè lo dereferenzi nei costruttori di Bar? Credo che la risposta dipenda da questo...se Foo foo è un oggetto, all'uscita da baz, Bar chiama il distruttore di default che a sua volta chiama il distruttore di foo perchè foo va out of scope; se foo è un puntatore ciò non avviene e rimane allocato in memoria una cella dedicata a Bar.foo->mem. Potrei sbagliarmi, ho ripreso a programmare da non molto dopo una pausa di qualche mese e i ricordi sono un po' offuscati.
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 28-11-2012, 12:54   #16
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da vendettaaaaa Guarda i messaggi
Ma non c'è qualcosa di sbagliato? Foo foo non è un puntatore, perchè lo dereferenzi nei costruttori di Bar? Credo che la risposta dipenda da questo...se Foo foo è un oggetto, all'uscita da baz, Bar chiama il distruttore di default che a sua volta chiama il distruttore di foo perchè foo va out of scope; se foo è un puntatore ciò non avviene e rimane allocato in memoria una cella dedicata a Bar.foo->mem. Potrei sbagliarmi, ho ripreso a programmare da non molto dopo una pausa di qualche mese e i ricordi sono un po' offuscati.
C'e' ovviamente una dereferenziazione di troppo
Il codice corretto e'
Codice:
struct Bar
{
   Foo foo;

   Bar(){ *foo.mem = 0; }

   Bar(int x)     
   {
       this->Bar::Bar();
       *foo.mem = x;
   }
};
Il discorso e' che tu chiami sia Bar(int) che Bar().
entrambi chiamano il costruttore di Foo() che quindi alloca memoria due volte.
Ma il distruttore viene chiamato solo una volta, per cui la memoria allocata la prima volta non viene liberata.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 28-11-2012, 13:17   #17
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da marco.r Guarda i messaggi
C'e' ovviamente una dereferenziazione di troppo
Il codice corretto e'
Codice:
struct Bar
{
   Foo foo;

   Bar(){ *foo.mem = 0; }

   Bar(int x)     
   {
       this->Bar::Bar();
       *foo.mem = x;
   }
};
Il discorso e' che tu chiami sia Bar(int) che Bar().
entrambi chiamano il costruttore di Foo() che quindi alloca memoria due volte.
Ma il distruttore viene chiamato solo una volta, per cui la memoria allocata la prima volta non viene liberata.
Allora mancava anche in baz la chiamata giusta
Cmq ho capito, grazie per avermelo fatto notare!
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando Due mesi di Battlefield 6: dalla campagna al bat...
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare Antigravity A1: drone futuristico per riprese a ...
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator Sony Alpha 7 V, anteprima e novità della ...
realme GT 8 Pro Dream Edition: prestazioni da flagship e anima racing da F1 realme GT 8 Pro Dream Edition: prestazioni da fl...
OVHcloud Summit 2025: le novità del cloud europeo tra sovranità, IA e quantum OVHcloud Summit 2025: le novità del cloud...
Apple in piena tempesta: anche il boss d...
Due GeForce GTX 580 in SLI: l'insospetta...
TSMC dà i numeri: dal processo N7...
La ricarica wireless dei Samsung Galaxy ...
Stop ai social per gli Under 16: l'Austr...
Google svela i videogiochi più ce...
TikTok lancia il nuovo feed con contenut...
Amazon aggiorna gli sconti e si prepara ...
GeForce NOW: 50% di sconto e 30 nuovi gi...
Insta360 Ace Pro 2 in offerta: disponibi...
Roborock Saros 10R a 909€ invece di 1.39...
Solo oggi due monitor Acer a prezzi assu...
FRITZ!Box in forte sconto su Amazon: mod...
Apple + Samsung = monopolio totale nel Q...
6 TV 4K in super sconto su Amazon, anche...
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: 20:52.


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