#include <iostream.h> #include <string> using namespace std; void tulosta(const string &cppS) { cout << cppS << endl; } void muuta_eka(string &cppS) { cppS[0] = 'R'; } void muuta_toka(string *cppS) { (*cppS)[1] = 'u'; } int main(void) { char cs1[10] = "Kissa"; string cppS1(cs1), cppS2("Koira"); // 1. tapa muuttaa cout << cppS1 << " " << cppS2 << endl; string cppS3,cppS4,cppS5; cppS3 = cs1; cppS4 = "Kana"; // 2. tapa muuttaa cppS5 = 'A'; // Jopa merkki voidaan sijoittaa cout << cppS3 << " " << cppS4 << " " << cppS5 << endl; tulosta(cppS4); // Toimii ilman muuta! tulosta(cs1); // Muuttaa automaattisesti cs1 => tilapäinen apujono tulosta("Mato"); // Muuttaa automaattisesti "Mato" => tilapäinen apujono muuta_eka(cppS3); tulosta(cppS3); // Tottakait toimii muuta_eka(cs1); tulosta(cs1); // Ei virheitä, mutta varoitus ja ei toimi muuta_eka("Emu"); tulosta("Emu"); // Onneksi ei toimi! Varoitus. muuta_toka(&cppS4); tulosta(cppS4);// Tottakait toimii // muuta_toka(&cs1); tulosta(cs1); // Ei käänny return 0; }Ohjelman tulostus:
Kissa Koira Kissa Kana A Kana Kissa Mato Rissa Kissa Emu KunaHuomattakoon, että esimerkiksi kutsusta muuta_eka(cs1); seuraa esimerkiksi varoitus:
Warn : c2cpp.cpp(35,17):Temporary used for parameter 'cppS' in call to 'muuta_eka(string &)'Tässä varoitetaan ohjelmoijaa siitä, että tilapäinen string- olio luodaan kutsun ajaksi, mutta tämä olio sitten häviää kutsun jälkeen ja cs1 jää muuttumatta ehkä vastoin ohjelmoijan toiveita. Tässäkin on hyvä esimerkki siitä, että varoitukset kannattaa ottaa todesta!
Kutsussa muuta_eka("Emu"); ei ole mitään järkeä, mutta sekin menee kääntäjästä läpi pelkällä varoituksella. Onneksi tulee se tilapäinen jono ja vakiomerkkijono jää muuttumatta!
Tähän asiaan osittain kuulumaton vaaranpaikka on taas osoittimissa. Jos aliohjelma muuta_toka olisikin ollut muodossa (oli nimittäin minulla ja kaatoi koneen):
void muuta_toka(string *cppS) { cppS[1] = 'u'; }menisi tämä täysin ilman varoituksia kääntäjästä lävitse. Eihän tässä nimittäin ole mitään virhettä. Lauseessahan vain käsketään sijoittamaan merkkijonotaulukon cppS toiseen paikkaan merkkijono u. Kirjain u muuttuu ensin automaattisesti merkkijonoksi ja tämä taas kuten aiemmin todettiin, voidaan sijoittaa C++ merkkijonoon. Taas yksi syy lisää VAROA osoittimia (ei kieltää niiden käyttöä). Toisaalta myös varoitus siitä, etteivät automaattiset tyypinmuunnokset ehkä sittenkään ole niin ihana asia!