Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: ifstreamin operator<< char-tyypille

Sisuaski [24.03.2008 14:17:45]

#

Joku standardia paremmin tunteva voisi kertoa, miksi olen väärässä kun oletan, että seuraava koodi kirjoittaisi tiedostoon (rivinvaihdon lisäksi) merkin 'A':

#include <fstream>
#include <ostream>
using namespace std;
int main()
{
	ofstream("file") << 'A' << endl;
}

Tuo koodi kirjoittaa tiedostoon kirjaimen sijaan tekstin "65", eli vaikuttaisi, että kääntäjä ei löytäisi ostream-otsikkotiedostossa olevaa funktiota operator<<(ostream&,char), vaan päätyisi kutsumaan ostreamin operator<<-funktiota int-tyypille.

Tästä huolimatta seuraavat toteutukset kuitenkin toimivat kuten odottaisikin, ja tulostavat A-kirjaimen tiedostoon kirjaimena, mikä tekee tilanteen sangen oudoksi.

ostream out("file");
out << 'A' << endl;
delete &(*new ofstream("file") << 'A' << endl);

koo [24.03.2008 19:00:35]

#

Tilapäisiä olioita ei voi välittää funktioille tavallisten viitteiden välityksellä vaan viitteen pitää olla const. Tilapäisten olioiden omia ei-const-funktioita saa kutsua. Esimerkiksi

struct huu {
  haa(huu &);
};

void hui(huu const &);
void hai(huu &);

int main() {
  hui(huu()); // ok
  hai(huu()); // error
  huu h;
  hai(h); // ok
  h.haa(huu()); // error
  huu().haa(h); // ok
}

Noniin, tämä oli pitkänpuoleinen esipuhe. Mutta siis, Kun sanotaan ofstream("file") ... ; syntyy tilapäinen olio, joka häviää puolipisteen jälkeen.

Sitten ofstreamista. Nyt on niin, että standardikirjastossa on suunnilleen nämä määritelmät:

class ofstream : public ostream {
  // ...
}

class ostream {
  // ...
  ostream &operator<<(int); // huom: luokan oma jäsenfunktio
}

ostream &operator(ostream &, char); // huom: luokan ulkopuolella

Tästähän se sitten jo näkyykin. Kun operaattoria << haetaan tilapäiselle ofstreamille ja charille, sopivin löytyy ostream-luokasta. Luokan ulkopuolista ei edes harkita, sillä tilapäinen ofstream-olio ei käy non-const-parametriksi. Kääntäjä muuntaa char-parametrin intiksi.

Kun luodaan nimetty ofstream-muuttuja, luokan ulkopuolella määritelty operaattori on sopivin char-parametrille.

Jotkut kääntäjät eivät aina tarkasta ja estä tilapäisten olioiden sidontaa non-const-viitteisiin funktioiden kutsuparametreissa. Esimerkiksi MSVC++ rikkoo oletusarvoisesti sääntöjä ellei erikseen käännä Microsoftin ekstensioita pois päältä (/Za).

Sisuaski [24.03.2008 19:22:29]

#

Kiitos, tämä selvitti asian.
Olisi kai pitänyt itsekkin tajuta tuo väliaikaismuuttujien rajoitus mutta ei sitten tullut ollenkaan mieleeni.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta