Newsgroup: it.comp.lang.c++
Titolo: Identificatore oggetto

Per verificare se un file, oggetto della classe ifstream, è stato aperto
correttamente utilizzo il seguente codice (suppongo standard).
ifstream in("input.txt");
if(!in) {
    cout<<"Impossibile aprire il file\n";
    exit();
}
Vengo dunque a chiedere: che cosa rappresenta l'identificatore dell'oggetto?
Quale significato ha l'espressione "in" (riferito all'esempio precedente)?
--
Francesco Trotta
http://space.tin.it/computer/ftrotta
Elimina "x_" dal mio indirizzo per mandarmi
un messaggio direttamente

...


 Quale significato ha l'espressione "in" (riferito all'esempio precedente)?
L'espressione "!in" utilizza implicitamente il metodo operator!() della
classe ifstream (ereditato, credo, da ios).
EMG

     suo puntatore ).
Due piccole correzioni:
1. Non esiste un oggetto "FILE". Semmai esiste un oggetto di classe
(tipo) ifstream.
2. La variabile in non contiene il puntatore all'oggetto (non è una
variabile puntatore) ma l'oggetto stesso. L'espressione "in" utilizza
implicitamente il metodo operator void*() della classe ifstream.
EMG

implicitamente il metodo operator void*() della classe ifstream.
Secondo te e' equivalente la forma        ( !in )  a quella
 ( in.is_open() ) ?
/Gianni

  ( in.is_open() ) ?
Non credo. L'operatore operator! restituisce fail() (almeno sul DJGPP) e
questo significa (credo) che c'è stato qualche errore nel file e non
solo che quest'ultimo non è aperto.
EMG

 solo che quest'ultimo non è aperto.
in (convertito in void*), dovrebbe essere equivalente a in.good(),
e quindi se `if (in)' ha successo lo stream dovrebbe essere pronto
per operazioni di I/O.
In un esempio Stroustrup usa `if (!in) error(...);' dopo l'apertura
di un ifstream, quindi dovrebbe andare bene, pero' non specifica se
e' equivalente a is_open o no.  Tutta la discussione su good, fail, 
bad, ... viene fatta con gli stream generici che non hanno apertura
e chiusura.
	Mauro

    suo puntatore ).
Permettimi di non essere d'accordo (almeno per quanto riguarda il mio
esempio).
Mi dici che l'identificatore di un oggetto rappresenta il puntatore alla
memoria allocata per l'oggetto. Tramite l'espressione "!in" in sostanza
quindi andrei a verificare che il puntatore sia un puntatore valido, cioč
che ci sia memoria allocata per l'oggetto della classe ifstream. Cioč a dire
che viene allocata memoria per un oggetto ifstream solo se riesco ad aprire
il file. E se non utilizzo il costruttore? Aspetta che utilizzi open() per
eventualmente allocare memoria? E allora come farei ad utilizzare open()?
Mi sembra quindi che la tua motivazione sia inconsistente. Fammi sapere se
ho capito male.


classe ifstream (ereditato, credo, da ios).
Quindi mi stai dicendo che in una classe base (pensi "ios") viene effettuato
l'overloading dell'operatore "!"?
Ne deduco che, in generale, l'espressione composta dall'identificatore di un
oggetto non ha alcun significato? E, quindi, "in" dell'esempio precedente
non significa niente?


> ( in.is_open() ) ?
Io ho provato il tuo codice. L'espressione !in e' sempre vera e quindi non e' equivalente a in.is_open(),
Antonio Donatiello

 non significa niente?
In C++ scrivere
if ( in ) ...
mi sembra sia equivalente a scrivere
if ( operator void*( in ) ) ...
naturalmente se in è un oggetto di qualche classe.
EMG

 Mi sembra quindi che la tua motivazione sia inconsistente.
Esattamente.
EMG

 Io ho provato il tuo codice. L'espressione !in e' sempre vera e quindi non e' equivalente a in.is_open(),
A me non risulta affatto che !in sia sempre vera. Esempio:
#include <fstream>
using namespace std;
void stampa( bool b )
{
    if ( b )
        cout << "Vero" << endl;
    else
        cout << "Falso" << endl;
}
int main()
{
    ifstream in( "prova.cc" );
    stampa( !in );
    stampa( in.is_open() );
    while ( in ) in.get();
    stampa( !in );
    stampa( in.is_open() );
}
da cui si vede che !in è vera solo quando, per qualsiasi motivo
(compreso l'eof), non si possono leggere caratteri dallo stream mentre
is_open() è vera solo se il file è stato aperto correttamente, anche se
non ci sono caratteri da leggere.
EMG

lo utilizza implicitamente quando scrivi, ad esempio
...
L'operatore "!" è l'operatore negazione. Se tu mi dici che tale operatore
viene ereditato da ifstream da qualche classe base significa che in tale
classe base ne viene eseguito l'overloading. Altrimenti non lo erediterebbe
e quindi sarebbe l'operatore negazione standard.
Ora, a parte tutto, in conclusione, l'espressione "!in" è la negazione dal
valore del puntatore all'oggetto, oppure assume il significato "aperto
con/senza successo" essendo l'operatore "!" ridefinito per una classe base
di ifstream (e quindi per ifstream)? (Nel primo caso ci sarebbe qualcosa che
non mi torna, nel secondo invece si).
Perdonate se insisto, ma ancora non ho capito bene :-)


 non mi torna, nel secondo invece si).
Assume il significato che gli dà la nuova definizione di operator!
presente in ios.
EMG

 Francesco Trotta
Ciao
*Fabio*

non ci sono caratteri da leggere.
Dal mio iostream.h:
int ios::operator! () { return fail(); }
in.fail() vale true se l'ultima operazione sullo stream non ha avuto 
successo.
Purtroppo gli stream sono un argomento molto delicato e ricco di
sfumature e non sono facili da capire e usare al meglio.
Paolo
-----------------------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
-----------------------------------------------------------------

naturalmente se in è un oggetto di qualche classe.
A me pare che
if (in)
sia equivalente a
if ( (bool)in )
e basta.
if (!in)
invece equivale a
if ( in.operator!())
se l'oggetto in fornisce un suo operatore di negazione
(definito public nella classe di in o in una sua classe base
da cui quella di in derivi pubblicamente).
if ( !( (bool)in ) )
altrimenti.


Chiedo scusa, ho sparato una eresia.... (si vede che non
mi sono ripreso dalle ferie o che le ferie non sono bastate)


 altrimenti.
Hai ragione anche qui. Grazie delle correzioni.
EMG

 mi sono ripreso dalle ferie o che le ferie non sono bastate)
Eppure a me, dagli esperimenti fatti, mi sembrava fosse giusto ciň che
hai detto. Come stanno veramente le cose? A questo punto sono confuso...
EMG



La cavolata stava nel fatto che come hai notato tu
if (in)
non e` semplicemente equivalente a if((bool)in)...
Infatti se la classe cui appartiene in non definisce l'operatore
di conversione a bool, il compilatore cerca di eseguire una
conversione a int o a puntatore (e da questa a bool). Presumibilmente
se manca "operator bool()" il compilatore prova ad utilizzare
una qualsiasi conversione ad un tipo integrale.
Quando ho scritto il messaggio ero convinto che il compilatore
cercasse *solo* la conversione a bool, poi per compatibilita` ho
pensato che andasse bene anche la conversione a int e con
un rapido esperimento ho scoperto che anche quella ad un
tipo puntatore va bene... Morale, la cosa e` molto piu`
complicata e ora vorrei scoprire l'ordine in cui viene cercato
un operatore di conversione. Vi faro` sapere...


l'ifstream. Sbaglio?
No, e` corretto... cmq vedi l'altro mio post.


 un operatore di conversione. Vi faro` sapere...
Bene. Un newsgroup serve anche a questi approfondimenti.
EMG