2013年9月14日土曜日

C++ 引数を参照にする 其の弐

今回は参照引数に const をつけて定数にすることの話です。

関数の引数をconst形式の参照にしてみる
前回は、関数の仮引数を参照にすると、関数の中から実引数の値を
変更できることを紹介しました。
しかし、実引数の値が変わると困ることが、往々にしてあります。
そんなときのために、このように仮引数にconstをつけることができます。

void NoChangeValue(const int &number);

引数がconst形式の参照となるため、値の変更ができなくなります。
では、それを確かめるサンプルプログラムです。

 #include <iostream>

using namespace std;

void NoChangeValue(const int &number); //const形式の参照

int main(void)
{
    int num1 = 500;

    NoChangeValue(num1);

    return 0;
}

void NoChangeValue(const int &number)
{
    number = 100;  //値を代入して、変更を試みます
}

すると、当然コンパイルエラーになります(ーー;)

# g++ -o test test.cpp
value.cpp: In function ‘void NoChangeValue(const int&)’:
value.cpp:18:14: error: assignment of read-only reference ‘number’

read-onlyと言われてしまいました。
確かに変更できなくなっていることがわかりましたね。^^


引数をconst形式の参照にすると何が良いか、どんなときに使う?
構造体などの大きなデータを関数に渡すときは、次のようなメリットがあるため
引数をconst形式の参照にする効果が期待できます。^^

  • 値渡しと同じように、実引数へ影響しない
  • 大きなデータの値渡しは、コピーに時間がかかってメモリも多く消費する

では、サンプルプログラムです。

include <iostream>

using namespace std;

struct Person{
    char name[32];
    int age;
};            //36バイトで全然大きくはないのですが、構造体を用意します

void PrintPersonReference(const Person &psn) //こちらは参照渡し
{
    cout << "Name : " << psn.name << endl;
    cout << "Age  : " << psn.age << endl;

    return;
}

void PrintPersonPointer(const Person *psn) //こちらはアドレス渡し
{
    cout << "Name : " << psn->name << endl;
    cout << "Age  : " << psn->age << endl;

    return;
}

int main(void)
{
    Person psn1 = { "Bob", 20 }; //構造体の宣言と同時に初期化しています

    PrintPersonReference(psn1);  //参照渡しでコール
    PrintPersonPointer(&psn1);    //アドレス渡しでコール
    return 0;
}

実行結果
# ./test2
Name : Bob
Age  : 20
Name : Bob
Age  : 20

まぁ、当然表示される結果は同じです(^_^;)
ですが、速いプログラムを書けるように、方法を知っておく必要があります。
あとは習うより慣れろ!ということですね。^^


今日の名言
雄弁に欠かせないものは誠実さである。自分に対して誠実な人間になれば、
人を説得することができる。
                                    ウィリアム・ハズリット

他人のために尽くすことだ。そうすれば、つまらない劣等感など、7月の畑にかかる
朝露のように、跡形もなく消え失せてしまう。
                                    デール・カーネギー

人は皆、深く根を下ろした興味や趣味を持つべきだ。精神は豊かになるし、生活が
グッと楽しくなる。そのうえ、興味の種類と性質によっては、自分の国に対して
貢献もできる。
                                    デール・カーネギー

目的をあくまで追求し、道徳を堅固に保ち、あくまで自分自身を守り通せば、
あらゆる目標が達成できるとともに、この心構え一つで、一段と大きな
仕事をする腹が決まる。
                                    フレデリック・B・ロビンソン