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);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 ulkopuolellaTä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).
Kiitos, tämä selvitti asian.
Olisi kai pitänyt itsekkin tajuta tuo väliaikaismuuttujien rajoitus mutta ei sitten tullut ollenkaan mieleeni.
Aihe on jo aika vanha, joten et voi enää vastata siihen.