2013年12月25日水曜日

C++ 仮想関数とオーバーライド


今回はオーバーライドにまつわるお話 其の弐 です。(^-^)

仮想関数とオーバーライドとは
派生クラスで再定義したメンバ関数を

基底クラスのポインタから呼び出すと

通常は再定義前のメンバ関数
(基底クラスのメンバ関数のこと)
が呼ばれます。



ここで再定義後のメンバ関数が呼ばれるようにするには、基底クラスで
その関数を仮想関数にしておく必要があります(^^;)

仮想関数にするには、予約語 virtual を指定します。
そして、仮想関数を派生クラスで定義し直すことをオーバーライドといいます。

では、仮想関数の使用例です。
class Food
{
public:
    virtual void SetPrice(int price);  //仮想関数を定義
    int GetPrice(void);
private:
    int m_price;
};
   :
void Vegetable::SetPrice(int price)  //派生クラスで
{                                                 //SetPrice()をオーバーライド
    Food::SetPrice(price * 2);           //倍返し価格設定
}
   :
int main(void)
{

    Food *pFood;
    Vegetable myVegetable;

    pFood = &myVegetable;
    pFood->SetPrice(500);    //VegetableクラスのSetPrice()を呼び出す
   :

実行結果
# ./test
Vegetable Price = 1000

「オーバーライド」と「オーバーロード」は言葉が似ています...
いつもごっちゃになるので注意したいところです(^^;)

今回のソース
#include <iostream>
#include <string.h>

using namespace std;

class Food
{
public:
    virtual void SetPrice(int price);
    int GetPrice(void);
private:
    int m_price;
};

class Vegetable : public Food
{
public:
    void SetPrice(int price);
    void SetFarmName(const char *farm);
    char *GetFarmName(void);
private:
    char m_strFarmName[32];
};

void Food::SetPrice(int price)
{
    m_price = price;
}

int Food::GetPrice(void)
{
    return m_price;
}

void Vegetable::SetPrice(int price)
{
    Food::SetPrice(price * 2);
}

void Vegetable::SetFarmName(const char *farm)
{
    strncpy(m_strFarmName, farm, 32);
}

char *Vegetable::GetFarmName(void)
{
    return m_strFarmName;
}

int main(void)
{

    Food *pFood;
    Vegetable myVegetable;

    pFood = &myVegetable;
    pFood->SetPrice(500);    //VegetableクラスのSetPrice()を呼び出す

    cout << "Vegetable Price = " << pFood->GetPrice() << endl;

    return 0;
}

今日の名言
満面にこぼれるような笑みをたたえ、肩をそびやかし、大きく深呼吸しながら歌の
一節でも口ずさむことだ。歌でなくて口笛でも良い。口笛が駄目なら鼻歌でも良い。
早い話が、幸福に酔いしれているようにふるまいながら、同時に浮かぬ顔で沈み込んで
いることは肉体的に不可能だということだ!
                                   デール・カーネギー

頭を悩ませる問題にぶつかった時でも、私は一時間以内にそうした悩みを追放して、
「素晴らしきかな人生」と歌声を上げることができる。私のやり方はこうだ。自分の
書斎へ入り、目を閉じたままで私は本を一冊抜き出す。それがこのプレスコットの
「メキシコ征服記」であろうとスエトニウスの「ローマ帝王記」であろうと、いっこうに
構わない。なおも目を閉じたままで、行き当たりばったりにページを開く。それから
目を開けて一時間読みふける。読めば読むほど、私は、世界が常に苦悶にあえいで
きたこと、文化が常に破滅の一歩手前にあったことを、痛感するのである。歴史書の
各ページは、戦争、飢餓、貧窮、疫病、人間同士の非人道的行為について、あますところ
なく述べている。一時間歴史をひもといてのち私は、なるほど現状はひどいには
違いないが、過去に比べるならはるかに良くなっていることをしみじみと悟る。
これにより、大局的には世界はだんだん良い方向に向かっていることが把握でき、
また私の悩みも、そのありのままの姿から検討できる。
                                   ロジャー・W・バブソン