cout << "\n" << "Blaah";
tai
cout << "\nBlaah";
(esim. Päivi Hietasen C++ kirjassa näin tehdään aina ja minusta
silloin komentoriviltä ajettuna seuraava prompti tulostuu
samalle riville).
Eihän Pascalissacaan tehty
writeln; write('Blaah');
vaan aina
writeln('Blaah');
Stroustrup itse käyttää muotoa
cout << "Blaah" << '\n';
(40 esimerkissä 310:stä on cout << "Blaah\n";
ja 3:ssa esimerkissä cout << "Blaah" << endl;
Tosin tuo 310 oli cout-rivien lukumäärä, ei aina rivinvaihtoon päättyvien)
Vesa
[ Moderoijat tavoittaa osoitteesta saom-...@cc.jyu.fi ]
[ Ryhmän säännöt: http://www.iki.fi/gaia/saom/saannot.html ]
[ Ryhmän FAQ: http://www.iki.fi/gaia/faq/sao-faq.html ]
Vesa> (esim. Päivi Hietasen C++ kirjassa näin tehdään aina ja minusta
Vesa> silloin komentoriviltä ajettuna seuraava prompti tulostuu
Vesa> samalle riville).
Olisiko selitys niin raadollinen, että ohjelmia ei ole testattu
MS-DOSin komentotulkin ulkopuolella? Kyseinen kyhäelmähän tulostaa
suoritetun ohjelman päätyttyä rivinvaihtomerkin ja uuden kehotteen.
Vesa> Stroustrup itse käyttää muotoa
Vesa> cout << "Blaah" << '\n';
Minä en ole ikinä ymmärtänyt, miksi lähes kaikissa C++-tyylioppaissa
ja -oppikirjoissa suositellaan käyttämään iostream-kirjastoa.
Optimoikohan yksikään markkinoilla oleva C++-kääntäjä tuota yhdeksi
operator<<()-metodikutsuksi? Olen käyttänyt C++-ohjelmissani syöttöön
ja tulostukseen stdio-kirjastoa, ja olen ollut siihen erittäin
tyytyväinen. Tuloskin vaikuttaa siirrettävämmältä (nimim. kerran
erästä iostream-kirjaston epästandardeja tai hiljattain lisättyjä
ominaisuuksia käyttävää ohjelmaa harmitellut).
Marko
>> cout << "Blaah" << '\n';
> Optimoikohan yksikään markkinoilla oleva C++-kääntäjä tuota yhdeksi
> operator<<()-metodikutsuksi?
Ei kai tuollaista saa tehdä?
http://www.cygnus.com/misc/wp/dec96pub/intro.html :
The observable behavior of the abstract machine is its sequence of
reads and writes to volatile data and calls to library I/O
functions.4)
--
= = = = Jori Mäntysalo - jm5...@uta.fi = = = =
"Itsestään selvää on, että nettipoliisien kanssa ei mistään asiasta pidä
olla eri mieltä. He tietävät kaiken! Tämän ymmärtäminen on askel kohti
hyväksyntää heidän taholtaan." - sfnet.keskustelu.nyyssit
> Minä en ole ikinä ymmärtänyt, miksi lähes kaikissa C++-tyylioppaissa
> ja -oppikirjoissa suositellaan käyttämään iostream-kirjastoa.
Kyllä iosteameilla ON helppo toteuttaa luokan dumppaus
ulos. Mulla on luokka (jolla on membereinä muita luokkia),
joka osaa dumpata ja lukea itsensä levyltä, toteutus
iostreameilla on melkein triviaali verrattuna siihen,
että scanffilla jne. sen toteuttaisi.
Mutta (formatoitu) numeroiden tulostus on iostreameilla
kyllä turhan hanakalaa.
--
Jyrki...@Helsinki.FI, University of Helsinki, Computing Centre
iostreamit ovat periaatteessa monessa suhteessa kauniimpi ratkaisu kuin
stdio. Paitsi, että muotoiltu tulostus on tyyppiturvallista, se myös
laajenee kivuttomasti joka suuntaan.
Voidaan toisaalta luoda täysin uusia streameja, joihin voi tulostaa. Ja
toisaalla voidaan luoda täysin uusia tulostettavia, joita voi
<<-operaattorilla tulostaa streameihin. Ja nämä kaikki toimivat ristiin.
Sen lisäksi, että voit oman luokan tulostaa cout:iin, voit tulostaa sen
myös stringstreameihin, tiedostoon tai vaikkapa oman, iostreameista
perityn kirjaston avulla verkon yli. Ja sama toiseen suuntaan.
Tämä siis teoriaa. Käytännössä (ns. oikeassa ohjelmoinnissa, ei
ohjelmoinnin opettelussa) esimerkiksi >>-operaattori streameihin on yhtä
käyttökelvoton kuin scanf C-kielessä, mutta tämä nyt on makuasia,
follarit /dev/nulliin. Sen sijaan <<-operaattori on IMO käytännössäkin
käyttökelpoinen.
Ja kun ajatellaan aloittelijoita, tulostaminen ja syöte ovat niitä
ensimmäisiä asioita, jotka ohjelmointikielellä halutaan tehdä, ja
ainakin tulostusta tarvitaan välittömästi käytännössä kaikissa
perusharjoitustöissä, jotta edes nähdään, tekeekö ohjelma likikään sitä,
mitä on tarkoitus. C:n printf- ja scanf-perheen funktiot ovat moneen
kertaan osoittautuneet hyvin hankaliksi aloittelijoille. Sotketaan
pointterien ja arvojen välittämisen kanssa, perinteiset %f vs. %lf
-ihmettelyt, "tää toimi kyllä mun koneella" -ongelmat jne. Lisäksi
stringeihin tulostaminen sprintf:llä on vaarallista ja snprintf on
standardoitu vasta C99:ssä. stdio:ssa on muitakin vaarallisia
funktioita, esimerkkinä vaikkapa gets.
Itse pitäisin erittäin huonona asiana, jos C++-oppikirjassa aloittelijaa
sotketaan heti printf- ja scanf-funktioilla. iostreamit ovat mielestäni
yksi hyvä syy aloittaa ohjelmointi suoraan C++:lla C:n sijaan, jos nyt
on välttämätön pakko näihin C:n sukuisiin kieliin heti sotkeutua.
> Tuloskin vaikuttaa siirrettävämmältä (nimim. kerran erästä
> iostream-kirjaston epästandardeja tai hiljattain lisättyjä
> ominaisuuksia käyttävää ohjelmaa harmitellut).
No C++:n implementaatiot, etenkin vanhemmat, nyt ovat mm. standardin
tuoreuden ja kompleksisuuden vuoksi monilta osin epästandardeja.
"Tämä bugaa jossain C++-implementaatiossa" ei mielestäni ole kuitenkaan
mikään syy hylätä jotain C++:lle ominaista piirrettä ja käyttää C:stä
perittyjä, heikompia ominaisuuksia sen sijaan, jos kyse on oppikirjasta.
Tuollaisesta on tietenkin hyvä varoittaa, ja kukin omalla kohdallaan
pohtikoot, käyttääkö moista ominaisuutta.
--
Jukka Suomela - http://www.iki.fi/suo/
Servin-Maijan tie 10 F 83, 02150 ESPOO, FINLAND
> Voidaan toisaalta luoda täysin uusia streameja, joihin voi tulostaa.
Ja
> toisaalla voidaan luoda täysin uusia tulostettavia, joita voi
> <<-operaattorilla tulostaa streameihin. Ja nämä kaikki toimivat
ristiin.
> Sen lisäksi, että voit oman luokan tulostaa cout:iin, voit tulostaa
sen
> myös stringstreameihin, tiedostoon tai vaikkapa oman, iostreameista
> perityn kirjaston avulla verkon yli. Ja sama toiseen suuntaan.
Olen joskus tutkinut käytännön toteutuksia periytetyistä output
streameista ja ne jos mitkä ovat masentavan monimutkaisia. Harmittaa,
kun niin yksinkertaisen asian toteuttamiseen täytyy harrastaa mitä
ihmeellisintä stream-akrobatiaa. Välillä jää kaipaamaan C++:aan Javan
kaltaisia kauniita String-toteutuksia, joissa tulostamiseen riittää yksi
yksinkertainen metodi.
Timo
Onko jotakin hyvaa syyta tulostaa rivinvaihto aina tulostuksen alkuun
eika koskaan loppuun?
Tyyliin:
cout << "\nBlaah";
Minun kiinostaa tama siksi, koska puolet opiskelijoista kayttaa
tuota (luettunaan kai mallia Hietasesta) ja puolet sitten minun
suosittelemaa
cout << "Blaah\n";
Ja nyt jos naita eri kategorioiden aliohjelmia yhdistelee, tietaa
mita tapahtuu. Haluaisin "standardoida" jommankumman tavan ja
jos kukaan ei tieda hyvaa syyta Hietasen tyylille, julistan
sen "pannaan".
Toinen kysymys:
Missa tilanteessa endl on pakollinen pelkan "\n":n tilalla?
1) Jokin pitkaa kestava suoritus ennen seuraavaa cout:ia?
2) cin on sidottu coutiin, joten sen kaytto tyhjentaa puskurin
automaattisesti, joten cin ei ole syy
3) Ohjelman loppu, eikos talloin puskurit tyhjenneta joka tapauksessa?
4) Muita syita?
Toisaalta kannattaako "turhaa" endl:n kaytto valttaa, eli jos tulostaa
20 rivia, onko kohtuutonta tulostaa endl jokaisen rivin peraan?
Enta 1000? Talla voisi kuvitella olevan eroa tiedostojen kohdalla,
jos endl (tai flush) todella pakottaa fyysiseen kirjoittamiseen
(pakottaako se edes?).
Vesa
Ehkäpä vastaamattomuus on hyvä osoitus siitä, ettei järkevää syytä
moiseen ole.
(OK, voi teoretisoida, että harvakseltaan tulostettaessa jollain
tietyllä platformilla saadaan tuolla tavalla ruudulla näkymään yksi rivi
enemmän, mutta tämäkin vaatii rivipuskuroimatonta ympäristöä ja on
hyötynä lähinnä teoreettinen.)
Haittoja tuosta sen sijaan on lukuisia. Tuorein tuloste jää puskureihin,
ohjelman alussa tulostetaan ylimääräinen tyhjä rivi, ohjelman lopussa
jää rivinvaihto tulostumatta ja lopputulos on esim. unixeissa
tyypillisesti ruma. Erityisesti tuoreimman tulosteen jääminen
puskureihin on monesti hyvin ikävää.
Lisäksi tuo tuntuu loogisesti omituiselta, tavallaan yhdistetään yhteen
lauseeseen palasia kahdesta loogisesta toiminnosta. Näen rivinvaihdon
nimenomaan tekstirivin loppumerkkinä (en alkumerkkinä) ja tekstirivin
tulostamisen lopettavine rivinvaihtoineen yhtenä loogisena toimintona.
Kannattaa myös huomata, mihin ohjelmoija voi vaikuttaa jättämällä sen
rivinvaihdon _pois_:
- rivinvaihto lopussa -periaatteessa tuo tarkoittaa "seuraava
tuloste jatkuu samalta riviltä",
- rivinvaihto alussa -periaatteessa tuo tarkoittaa: "tämä tuloste
tulee samalle riville edellisen kanssa".
Kokemuksesta ensimmäinen vaihtoehto tuntuu hyödyllisemmältä.
Ja vielä: En ole aikaisemmin nähnyt missään suosittavan rivinvaihtoa
alussa. "Kaikki" olemassaoleva koodi käyttää rivinvaihtoa lopussa. Jo
C:n standardikirjastossa esimerkiksi rivin tulostaminen puts:llä
nimenomaan lisää rivinvaihdon loppuun. Jos omassa koodissa käytetään
rivinvaihtoa alussa, se sotii siis kaiken olemassaolevan koodin kanssa,
aiheuttaa päänvaivaa jne. Vaikka rivinvaihto alussa olisi jonkun
mielestä jopa järkevämpi, tämä olemassaoleva käytäntö on jo mielestäni
yksinäänkin riittävän hyvä syy suosia rivinvaihtoa lopussa. Näin
kirjastofunktiot ja muiden kirjoittamat osuudet pelaavat yhteen oman
koodin kanssa.
> Ja nyt jos naita eri kategorioiden aliohjelmia yhdistelee, tietaa
> mita tapahtuu. Haluaisin "standardoida" jommankumman tavan ja
> jos kukaan ei tieda hyvaa syyta Hietasen tyylille, julistan
> sen "pannaan".
Julista ihmeessä. Toivottavasti tässä on kylliksi perusteita moisen
järjettömyyden vastustamiseen. :)
--
Jukka Suomela - http://www.iki.fi/suo/
Servin-Maijan tie 10 F 83, 02150 ESPOO, FINLAND
[ Moderoijat tavoittaa osoitteesta saom-...@cc.jyu.fi ]
Nopeasti vilkaistuani Visual C++ 6.0:n toteutusta coutille ja "<<"
operaattorille, niin näyttäisi siltä, että mitään teknistä syytä "\n" merkin
käytöstä ennen tekstiä ei ole. Toisin sanoen: "<<" operaattori ei välitä
kirjoitettavan tekstin sisällöstä (Lukuunottamatta '\0' ja EOF-merkkiä), se
vain kopio tekstin toisella muistialueelle tai puskee johonkin järjestelmän
resurssiin (porttiin, ajuriin...). Tietenkin Visual C++:n toteutus ei sulje
pois sitä mahdollisuutta, että jossakin toisessa järjestelmässä tai
erityyppisessä streamissä "\n" merkin sijainnilla olisi jotain merkitystä.
Joitakin mahdollisia "ei teknisiä" syitä, JOISSAKIN mahdollisissa
tilanteissa:
1) Edellisellä kirjoituskerralla ei tiedetä varmuudella milloin rivinvaihto
on syytä laittaa, esim:
while( pMsg->IsMessageEnded() != true )
{
cout << pMsg->WaitMessage();
}
cout << "\nEnd of Message\n";
2) Halutaan varmistua siitä, että teksti tulee omalle riville. (Ei tiedetä
varmuudella,
että tuliko rivivaihtoa edellisen rivin loppuun.)
- Tulostaminen tapahtuu usean funktion välityksellä.
- Odotettiin MS-DOS:ssa yhden näppäimen painallusta.
Muistini mukaan MS-DOS:ssa jäi yksi tyhjä rivi ohjelman viimeisen rivin ja
komentokehotteen väliin, jos rivinvaihdon laittoi loppuun. En tosin jaksanut
alkaa varmentamaan tätä...
> Toinen kysymys:
> Missa tilanteessa endl on pakollinen pelkan "\n":n tilalla?
> 1) Jokin pitkaa kestava suoritus ennen seuraavaa cout:ia?
> 2) cin on sidottu coutiin, joten sen kaytto tyhjentaa puskurin
> automaattisesti, joten cin ei ole syy
> 3) Ohjelman loppu, eikos talloin puskurit tyhjenneta joka tapauksessa?
> 4) Muita syita?
>
> Toisaalta kannattaako "turhaa" endl:n kaytto valttaa, eli jos tulostaa
> 20 rivia, onko kohtuutonta tulostaa endl jokaisen rivin peraan?
> Enta 1000? Talla voisi kuvitella olevan eroa tiedostojen kohdalla,
> jos endl (tai flush) todella pakottaa fyysiseen kirjoittamiseen
> (pakottaako se edes?).
Visual C++:ssa endl määritellään seuraavalla tavalla (pitäisi päteä myös
muihin kääntäjiin):
inline _CRTIMP1 ostream& __cdecl endl(ostream& _outs) { return _outs << '\n'
<< flush; }
Eli endl = rivinvaihto + flush. Toisin sanoen "endl" ei ole pakollinen. Voit
käyttää aivan yhtä hyvin rivinvaihtoa ja flushia erikseen. (Itse käyttäisin
rivinvaihto + flushia, koska se parantaa koodin luettavuutta ja
ymmärrettävyyttä.)
Flushia kannattaa taas yleensä kutsua aina silloin, kun jotain isompi töistä
on saatu päätökseen ja aletaan tekemään jotain uutta osatyötä, jossa jotain
voi mennä pahasti vikaan. Toinen tilanne on kun halutaan tyhjentään
lukupuskuri sinne kertyneestä roskasta. (Esimerkiksi: otetaan käyttäjältä
vain ensimmäinen näppäimen painallus.) Flushin kutsuminen luonnollisesti
hidastaa hieman koodin ajoa, mutta esimerkiksi kirjoitettaessa levylle
tietoja, käyttäjä ei nykyaikaisella nopealla koneella tule luultavasti
huomaamaan eroa.
Mitään 100% taetta flush ei anna tietojen tallentamista. Esimerkiksi
kirjoitettaessa levylle, tieto siirtyy nykyaikaisessa käyttöjärjestelmässä
levypuskuriin ja sieltä levylle - sitten kun käyttöjärjestelmällä sattuu
olemaan aikaa tietojen kirjoittamiseen. Jos haluaa varmistaa tietojen
tallentamisen, niin kannattaa käyttää tietokantoja tai rautatasolle menevää
koodia. Ohjelman loppuessa ainakin Visual C++:n toteutuksessa kutsutaan
flushia.
BTW: Itse en ole kertaakaan kenenkään nähnyt käyttävän iostream kirjastoa
työelämässä tai edes opiskelun ohessa. Itseasiassa tämä taisi olla
ensimmäinen kerta, kun tavaan iostreamin ohjeita ja koodia Hietasen ( +
muiden C++ kirjojen ) lueskelun jälkeen. (Muutenkin iostreamien ja STL:n
käyttö Windows ohjelmoinnissa on enemmänkin poikkeus kuin sääntö...)
- Mikko K. Puonti
-------------------------------------------------------
"Even if you're on the right track, you'll get run over
if you just sit there." -Will Rogers
Kyllä. flush on määritelty ostreameille ja se mahdollistaa puskurin
tyhjentämisen eksplisiittisesti.
Huomaa, että tässä _ei_ ole kyse siitä, että dataa hukattaisiin. Kyse on
vain siitä, missä vaiheessa data oikeasti kirjoitetaan kohteeseensa.
> Toinen tilanne on kun halutaan tyhjentään lukupuskuri sinne
> kertyneestä roskasta. (Esimerkiksi: otetaan käyttäjältä vain
> ensimmäinen näppäimen painallus.)
Tähän flushia näkee kyllä paljon käytettävän, mutta käsittääkseni
flushia ei ole standardeissa lainkaan määritelty istreameille.
Mielestäni ei ole myöskään mitenkään itsestäänselvää, että istreamin
flush nimenomaan hukkaisi lukemattomat datat puskureista. Sehän on aivan
eri asia kuin mitä se tekee ostreamien kanssa.
Sama koskee fflush():n käyttöä C:ssä syöttö- ja tulostus-streamien
kanssa.
Viisaammat korjatkoot.
> BTW: Itse en ole kertaakaan kenenkään nähnyt käyttävän iostream kirjastoa
> työelämässä tai edes opiskelun ohessa. Itseasiassa tämä taisi olla
> ensimmäinen kerta, kun tavaan iostreamin ohjeita ja koodia Hietasen ( +
> muiden C++ kirjojen ) lueskelun jälkeen. (Muutenkin iostreamien ja STL:n
> käyttö Windows ohjelmoinnissa on enemmänkin poikkeus kuin sääntö...)
Ohjelmointia on Windows-maailman ulkopuolellakin. Esimerkiksi
komentoriviltä ajettavien Unix-apuohjelmien kirjoittamisessa ja vaikkapa
CGI-ohjelmien kirjoittamisessa en näe, miksi iostreamit olisivat
olennaisesti huonompi tapa tulostaa kuin esimerkiksi C:n
tulostusfunktiot (fputs, *printf ja kumppanit).
Mielenkiinnosta, kun en ole juurikaan Windows-ohjelmointia C++:lla
harrastanut: Miksi STL:ää vältellään Windows-ohjelmoinnissa? Onko STL:n
implementaatiot kääntäjissä tai kääntäjien template-tuki yleensä heikkoa
vai tarjoavatko kääntäjät omia, korvaavia kirjastoja?
--
Jukka Suomela - http://www.iki.fi/suo/
Servin-Maijan tie 10 F 83, 02150 ESPOO, FINLAND
[ Moderoijat tavoittaa osoitteesta saom-...@cc.jyu.fi ]
Olet oikeassa. Flushia ei ole määritelty istreamille, eikä sitä myöskään ole
Visual C++:n toteutuksessa. Minun erheeni. (Tässä näkee sen kuika vähän olen
käytellyt streameja.)
> Mielestäni ei ole myöskään mitenkään itsestäänselvää, että istreamin
> flush nimenomaan hukkaisi lukemattomat datat puskureista. Sehän on aivan
> eri asia kuin mitä se tekee ostreamien kanssa.
>
> Sama koskee fflush():n käyttöä C:ssä syöttö- ja tulostus-streamien
> kanssa.
Nopean vilkaisu Visual C++:n ohjeisiin kertoo fflushista seuraavaa:
"The fflush function flushes a stream. If the file associated with stream is
open for output, fflush writes to that file the contents of the buffer
associated with the stream. If the stream is open for input, fflush clears
the contents of the buffer. fflush negates the effect of any prior call to
ungetc against stream. Also, fflush(NULL) flushes all streams opened for
output. The stream remains open after the call. fflush has no effect on an
unbuffered stream."
Koodista katsottuna, VC++:n toteutus kirjoittaa ensin kaikki tiedot
tiedostoon (jos kyseessä on write(/read) tiedosto) ja sitten nollaa streamin
puskurinsijainnin alkuun, myös readonly tyyppisten tiedostojen puskurin.
Tietenkään VC++:n toteutus ei kerro yhtään mitään muiden järjestelmien
toteutuksesta, mutta ainakin ohjeet väittävät fflushin olevan ANSI
yhteensopiva (joten olettaisin, että fflush käyttäytyminen on samanlaista
myös muissa järjestelmissä).
> > BTW: Itse en ole kertaakaan kenenkään nähnyt käyttävän iostream
kirjastoa
> > työelämässä tai edes opiskelun ohessa... (Muutenkin iostreamien ja STL:n
> > käyttö Windows ohjelmoinnissa on enemmänkin poikkeus kuin sääntö...)
>
> Mielenkiinnosta, kun en ole juurikaan Windows-ohjelmointia C++:lla
> harrastanut: Miksi STL:ää vältellään Windows-ohjelmoinnissa? Onko STL:n
> implementaatiot kääntäjissä tai kääntäjien template-tuki yleensä heikkoa
> vai tarjoavatko kääntäjät omia, korvaavia kirjastoja?
Syitä on varmasti lukuisia. Tässä muutamia:
- Windows maailmassa elää rinnan (ainakin) kolme erilaista merkkien
koodausmuotoa (ASCII/ANSI, UNICODE ja BSTR), joiden välillä pitää tehdä
muunnoksia. Tällä hetkellä ainakin VC++:n iostream kirjaston toteutus ei
käsittääkseni koske kuin ANSIa ja UNICODEa.
- Yleensä Windowsissa kaikenlaisten merkkijonojen ja tiedostojen käsittely
on suhteellisen vähäistä (jos sitä vertaan UNIX:iin), joten iostreamin
kalttaisia luokkia ei tarvita yhtäpaljon. Merkkijonot tallennettaan ohjelman
resursseihin, käyttäjät antavat komentonsa hiirellä ja käyttöjärjestelmän ja
muiden ohjelmien kanssa keskustellaan API kutsujan ja COM rajapintojen
välillä (eikä asetus/komentotiedostojen ja erilaisten
käynnistysrivikomentojen kanssa).
- Toisaalta erilaisten luokkakirjastojen mukana tulee omat luokat jotka
toteuttavat tarvittavat toiminnot riittävän hyvin ja ovat paljon helpompia
ymmärtää ja käyttää. Samaiset luokkakirjastot tavallisesti myös tukevat vain
omia luokkiaan. Nykyisin myös COM aiheuttaa pientä lisäepäyhteensopivuutta
iostreamien kanssa omalla IPersistent rajapinta perheellään.
- STL:n ja iostreamin koodin kirjoitusasu poikkeaa myös Windowsin
unkarilaisesta notaatiosta, joten iostreamin ja STL:n käyttäminen aiheuttaa
kauneus virheitä koodiin.
En tarkoita tällä kumminkaan sitä, että STL ja iostream olisivat huonompia
kuin jonkin luokkakirjaston ratkaisut. Itseasiassa STL ja iostream toteutus
on tietämäni mukaan tavallisesti tehokkaampi ja luotettavampi kuin vastaava
luokkakirjaston ratkaisu. Mutta valitettavasti ne luokkakirjastot, jotka
ovat saanet "graafisen käyttöliittymän standardikirjaston" aseman
Windowsissa, eivät tue riittävästi STL tai iostreamia...
Kääntäjien template tuki on nykyisin hyvällä tasolla. Esimerkiksi VC++ on tu
kenut (käsittääkseni) täysin ANSIn (ISO WG21/ANSI X3J16) mukaisia
templateita versiosta 5.0 lähtien. Hyvänä esimerkkinä templateista Windows
maailmassa voi pitää ATL (Active Template Library) luokkakirjastoa. Voit
esimerkiksi määritellä sillä tämän näköisen luokan...
class ATL_NO_VTABLE CFullCompositeCtrl :
public CComObjectRootEx<CComSingleThreadModel>,
public IDispatchImpl<IFullCompositeCtrl, &IID_IFullCompositeCtrl,
&LIBID_ATLESIMLib>,
public CComCompositeControl<CFullCompositeCtrl>,
public IPersistStreamInitImpl<CFullCompositeCtrl>,
public IOleControlImpl<CFullCompositeCtrl>,
public IOleObjectImpl<CFullCompositeCtrl>,
public IOleInPlaceActiveObjectImpl<CFullCompositeCtrl>,
public IViewObjectExImpl<CFullCompositeCtrl>,
public IOleInPlaceObjectWindowlessImpl<CFullCompositeCtrl>,
public ISupportErrorInfo,
public IConnectionPointContainerImpl<CFullCompositeCtrl>,
public IPersistStorageImpl<CFullCompositeCtrl>,
public ISpecifyPropertyPagesImpl<CFullCompositeCtrl>,
public IQuickActivateImpl<CFullCompositeCtrl>,
public IDataObjectImpl<CFullCompositeCtrl>,
public IProvideClassInfo2Impl<&CLSID_FullCompositeCtrl,
&DIID__IFullCompositeCtrlEvents, &LIBID_ATLESIMLib>,
public IPropertyNotifySinkCP<CFullCompositeCtrl>,
public CComCoClass<CFullCompositeCtrl, &CLSID_FullCompositeCtrl>
{
public:
CFullCompositeCtrl()
{
m_bWindowOnly = TRUE;
CalcExtent(m_sizeExtent);
}
DECLARE_REGISTRY_RESOURCEID(IDR_FullCompositeCtrl)
DECLARE_PROTECT_FINAL_CONSTRUCT()
...
... Noin 2-6 kk kuukauden opiskelun jälkeen tavallinen ohjelmoija ymmärtää
mitä tuossa tehdään... ;)
(...Java koodareilla menee hieman kauemmin...)
Mikko K. Puonti
-------------------------------------------------------
"Even if you're on the right track, you'll get run over
if you just sit there." -Will Rogers
[ Moderoijat tavoittaa osoitteesta saom-...@cc.jyu.fi ]
ANSI C standardi ei takaa mitä fflush():in kutsuminen input steamille
vaikuttaa. Eli kyseessä on ns. 'implementation defined behaviour'.
Ville