Newsgroup: it.comp.lang.c++
Titolo: un warning sbagliato? (o quantomeno sospetto)

ho il seguente problema, che e' schematizzato in questo programmino 
quasi minimale (alla fine, se servisse, c'e' la spiegazione):
#include <iostream>
class Base
{
public:
	Base() { std::cout << "Base\n"; std::cout.flush(); }
	virtual ~Base() { std::cout << "~Base\n"; std::cout.flush(); }
	virtual char* Name() const { return "Base"; }
};
class Derived : public Base
{
public:
	Derived() { std::cout << "Derived\n"; std::cout.flush(); }
	~Derived() { std::cout << "~Derived\n"; std::cout.flush(); }
	char* Name() const { return "Derived"; }
};
Derived foo()
{
	std::cout << "foo function\n"; std::cout.flush();
	return Derived();
}
int main()
{
	std::cout << "begin of the program\n"; std::cout.flush();
	const Base& obj = foo();
	std::cout << "this is the program body\n"; std::cout.flush();
	return 0;
}
Base ha metodi virtuali, e Derived e' la sua derivata che sovrascrive 
dei metodi. foo() ritorna un oggetto Derived, che e' un temporaneo che 
tengo in vita assegnandolo ad una reference const di tipo Base nel main. 
In linea di massima, mi serve solo questo, perche' sono interessato che 
Derived esegua il codice del distruttore all'uscita del metodo (potrebbe 
essere una Guard). Pero' non devo chiamare alcun metodo su obj.
Il compilatore mi da un warning dicendomi che obj non viene 
utilizzato... a non e' vero! Le cose le fa nel distruttore....
Non capisco! (sia gcc che il visual fanno lo stesso).
Grazie per i consigli!
Ciao,
Zeppe

 utilizzato... a non e' vero! Le cose le fa nel distruttore....
Mai visto un reference con un distruttore.
Obj semplicemente non serve.
int main()
{
	std::cout << "begin of the program\n"; std::cout.flush();
	/*const Base& obj = */foo();
	std::cout << "this is the program body\n"; std::cout.flush();
	return 0;
}
Kiuhnm

Kiuhnm wrote:
[...]
Te pareva...
Kiuhnm

 Obj semplicemente non serve.
Avevo letto il post in fretta...
Non č che obj fa le cose nel distruttore: obj č un reference.
Solitamente un temporaneo viene distrutto dopo che l'espressione che lo 
contiene č stata valutata.
Il reference lo mantiene in vita piů a lungo quindi "this is the program 
body\n" viene stampato prima.
Quando obj viene distrutto, il temporaneo viene distrutto. Non č obj a 
distruggere direttamente il temporaneo (almeno concettualmente).
A questo punto direi che il warning č comprensibile, perň fuori posto.
Comunque č solo un avvertimento, appunto.
Prova cosě:
int main()
{
     std::cout << "begin of the program\n"; std::cout.flush();
     const Base& obj = foo();
     sizeof(obj);



il reference e' l'unico modo che ho di allungare la vita dell'oggetto 
che ritorno, fino alla fine della funzione, e per di piu' in modo 
polimorfo. L'alternativa, a questo punto, potrebbe essere qualcosa come 
uno smart pointer... ma e' una complicazione brutta e inutile.
Zeppe

 }
warning: statement has no effect
e come dargli torto? E' un workaround che avrei comunque preferito 
evitare :)
Zeppe

 evitare :)
Dimenticavo che in "release" non dà i warning.
---
const Base& obj = foo();
// Evita un warning indesiderato e che non ha motivo d'essere.
int ok = sizeof(obj);
++ok;
---
Kiuhnm


Azz, pero', che giro :D
A questo punto, tanto valeva, piu' elegante e chiaro un bel:
class Base{
// ...
	void DoNothing() const { }
}
e poi obj.DoNothing();
ma io volevo una soluzione pulita... :((
Zeppe

 }
A me pare più invasivo. Vai addirittura a modificare la classe!
Fatti una macro e amen.
Kiuhnm