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 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).
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.