2013年12月16日月曜日

C++ 派生クラスと基底クラス 其の一

今回は、派生クラスのオブジェクトを基底クラスへ代入するという
ことについて見ていきます(^^)

子オブジェクトを親オブジェクトに代入してみる
派生クラスのオブジェクトは、基底クラスのオブジェクトへ
代入することができます。
代入すると、派生クラスのメンバ変数の値が、
そのまま対応する基底クラスのメンバ変数にコピーされるのです(^^)/ さすがC++ 賢い!

かなり省略してますが、以前のプログラムを利用した例です。

class Food
{
    :               //基底クラスFoodの定義
};

class Vegetable : public Food
{
    :              //派生クラスVegetableの定義
};

    :

int main(void)
{
    Vegetable Pumpkin;  //Pumpkinオブジェクト生成
    Food myFood;         //myFoodオブジェクト生成

    Pumpkin.SetPrice(398);
    cout << "Price = " << Pumpkin.GetPrice() << endl;

    Pumpkin.SetFarmName("Pascal's Farm");
    cout << "Farm Name = " << Pumpkin.GetFarmName() << endl;

    myFood = Pumpkin;  //Pumpkinオブジェクトを代入
    cout << "myFood's price " << myFood.GetPrice() << endl;
  
    return 0;
}

実行結果はこうなります。(^^)
# ./test
Price = 398
Farm Name = Pascal's Farm
myFood's price 398

おぉ、Foodクラスの方では、SetPrice() を呼び出していないのに
価格が設定されているではありませんか!

親オブジェクトを子オブジェクトへ代入してみると?
一方で、基底クラスのオブジェクトを派生クラスのオブジェクトに
代入するとどうなるのでしょう。試してみます。(^^;)

int main(void)
{
    Vegetable Pumpkin;
    Food myFood;

    Pumpkin.SetPrice(398);
    cout << "Price = " << Pumpkin.GetPrice() << endl;

    Pumpkin.SetFarmName("Pascal's Farm");
    cout << "Farm Name = " << Pumpkin.GetFarmName() << endl;

    myFood.SetPrice(200);  //基底クラスに設定した値が   
    Pumpkin = myFood;      //派生クラスに反映されるのでしょうか?

結果は、コンパイルエラーです...(*´Д`)
派生クラスにしかないメンバ変数に値が設定できないのです。
これでは困るので、親から子へ代入ができないのです。

ちなみに、こんなメッセージが出ます。
test.cpp: In function ‘int main()’:
test.cpp:57:15: error: no match for ‘operator=’ in ‘Pumpkin = myFood’
test.cpp:57:15: note: candidate is:
test.cpp:15:7: note: Vegetable& Vegetable::operator=(const Vegetable&)
test.cpp:15:7: note:   no known conversion for argument 1 from ‘Food’ to ‘const Vegetable&’

実は、もっと後に出すつもりの演算子のオーバーロードという機能を使えば
このエラーそのものは、無くすことができます。
ただし、それはまた後ほど...(^^;)

今日の名言
ふとっちょ卵が塀の上、ふとっちょ卵が落ちちゃった。
王様の馬と王様の家来が皆出て来てくっつけたけど、元通りにはならないよ。
この古い童話にある通り、王様の馬と家来が全部束になってかかっても、過去は
元通りにはならない。一旦おがくずになったものをのこぎりで挽いても始まらない。
                                デール・カーネギー

私は実業界に入って間もなく、心配することのばからしさを思い知らされた。だから
私は、難問にはできる限り手を尽くすように心がけているが、もし目算が外れて、
収拾がつかなくなったとしても、あっさり忘れることにしている。
                                ジュリアス・ローゼンウォルト

私は他に気がかりなことがあるとしても、それに関連する事柄全てを忘れ去り、
当面の仕事に没頭することにしている。その効果は実に素晴らしい。
                                ヘンリー・ウォード・ビーチャー