問題6:virtualと仮想関数

この問題を解くためには…
 → 応用編第6日目参照

probex6-2.(難易度:★)

以下のプログラムは、二種類の飛行機、戦闘機(FighterAircraft)と、旅客機(PassengerPlane)クラスのインスタンスを生成し、メンバ関数を実行するプログラムである。この2つのクラスには、共通するメンバが存在する。

そこで、これら2つのクラスに共通するメンバを、飛行機(AirPlane)クラスに集約し、FighterAiracraftクラス、およびPassengerPlaneは、それらのクラスを継承したものにするように、プログラムを書きかかえなさい。ただし、この時、AirPlaneは、完全仮想関数fly()を持つ抽象クラスとすること。

fighteraircraft.h
#ifndef _FIGHTERAIRCRAFT_H_
#define _FIGHTERAIRCRAFT_H

#include <iostream>
#include <string>

using namespace std;

//	戦闘機クラス
class FighterAircraft{
private:
	string m_type;
public:
	//	コンストラクタ
	FighterAiracraft();
	//	タイプの取得
	string getType();
	//	飛行する
	void fly();
	//	戦闘する
	void fight();
};

#endif // _FIGHTERAIRCRAFT_H_
fightercraft.cpp
#include "figheraircraft.h"

//	コンストラクタ
FighterAircraft::FighterAircraft()
{
	m_type = "戦闘機";
}
//	タイプの取得
string FighterAircraft::getType()
{
	return m_type;
}
//	飛行する
void FighterAircraft::fly()
{
	cout << "攻撃に出るために飛行" << endl;
}
//	戦闘する
void FighterAircraft::fight()
{
	cout << "戦闘します" << endl;
}
passengerplane.h
#ifndef _PASSENGERPLANE_H_
#define _PASSENGERPLANE_H_

#include <iostream>
#include <string>

using namespace std;

//	旅客機クラス
class PassengerPlane{
private:
	string m_type;
public:
	//	コンストラクタ
	PassengerPlane();
	//	タイプの取得
	string getType();
	//	飛行する
	void fly();
	//	乗客を運ぶ
	void carryPassengers();
};

#endif // _PASSENGERPLANE_H_
passengerplane.cpp
#include "passengerplane.h"

//	コンストラクタ
PassengerPlane::PassengerPlane()
{
	m_type = "旅客機";
}
//	タイプの取得
string PassengerPlane::getType()
{
	return m_type;
}
//	飛行する
void PassengerPlane::fly()
{
	cout << "乗客を乗せて目的地まで飛行します。" << endl;
}
//	乗客を運ぶ
void PassengerPlane::carryPassengers()
{
	cout << "乗客を目的地まで運びます" << endl;
}
main.cpp
#include <iostream>
#include "fighteraircraft.h"
#include "passengerplane.h"

using namespace std;

int main(){
	//	戦闘機クラスのインスタンスの生成
	FighterAircraft* fighter = new FighterAircraft();
	PassengerPlane* airlinear = new PassengerPlane();
	//	戦闘機クラスの処理
	fighter->fly();					//	飛行する
	fighter->fight();				//	戦闘する
	//	旅客機クラスの処理
	airlinear->fly();				//	飛行する
	airlinear->carryPassengers();	//	乗客を運ぶ
	//	delete処理
	delete fighter;
	delete airlinear;
}
実行結果
攻撃に出るため飛行
戦闘します
乗客を乗せて目的地まで飛行します。
乗客を目的地まで運びます。

probex6-1.(難易度:★★)

以下のプログラムは、野球選手(BaseballPlayer)クラスを基に派生した、ピッチャー(Pitcher)クラス、捕手(Catcher)クラス、野手(Fielder)クラスのインスタンスをチームのメンバーの数だけ生成し、その内容を表示したプログラムである。PitcherクラスおよびFielderクラスを参考にして、捕手(Catcher)クラスを作成し、プログラムを完成させなさい。

baseballplayer.h
#ifndef _BASEBALLPLAYER_H_
#define _BASEBALLPLAYER_H_

#include <iostream>
#include <string>

using namespace std;

class BaseballPlayer{
protected:
	//	背番号
	int m_number;
	//	プレイヤーの種類
	string m_kind;
	//	名前
	string m_name;
public:
	//	名前の取得
	int getNumber();
	//	種類の取得
	string getKind();
	//	名前の取得
	string getName();
	//	プレイ(純粋仮関数)
	virtual void play()=0;
};

#endif // _BASEBALLPLAYER_H_
fielder.h
#ifndef _FIELDER_H_
#define _FIELDER_H_

#include "BaseballPlayer.h"

class Fielder : public BaseballPlayer{
public:
	//	コンストラクタ
	Fielder(string name,int number);
	//	野手がプレイする
	void play();
};

#endif // _FIELDER_H_
fielder.cpp
#include "fielder.h"

Fielder::Fielder(string name,int number) 
{
	m_name = name;
	m_number = number;
	m_kind = "キャッチャー";
}
//	ピッチャーがプレイする
void Fielder::play()
{
	cout << "ピッチャーの球を受ける" << endl;
}
pitcher.h
#ifndef _PITCHER_H_
#define _PITCHER_H_

#include "BaseballPlayer.h"

class Pitcher : public BaseballPlayer{
public:
	//	コンストラクタ
	Pitcher(string name,int number);
	//	ピッチャーがプレイする
	void play();
};

#endif //_PITCHER_H_
pitcher.cpp
#include "pitcher.h"

Pitcher::Pitcher(string name,int number)
{
	m_name = name;
	m_number = number;
	m_kind = "ピッチャー";
}
//	ピッチャーがプレイする
void Pitcher::play()
{
	cout << "投球する" << endl;
}
main.cpp
#include "pitcher.h"
#include "catcher.h"
#include "fielder.h"

int main(){
	//	野球選手の配列作成
	BaseballPlayer* players[9];
	players[0] = new Fielder("山田",8);
	players[1] = new Fielder("高坂",16);
	players[2] = new Fielder("ゴメス",16);
	players[3] = new Fielder("中村",6);
	players[4] = new Fielder("春日井",32);
	players[5] = new Fielder("堀田",5);
	players[6] = new Catcher("逢坂",54);
	players[7] = new Fielder("トーマス",11);
	players[8] = new Pitcher("斉藤",34);
	int i;
	for(i = 0; i < 9; i++){
		cout << "---------------------------------------------" << endl;
		cout << "名前:" << players[i]->getName() << endl;
		cout << "背番号:" << players[i]->getNumber() << endl;
		cout << "種類:" << players[i]->getKind() << endl;
	}	
	//	インスタンスの消去
	for(i = 0; i < 9; i++){
		delete players[i];
	}
	return 0;
}
実行結果
---------------------------------------------
名前:山田
背番号:8
種類:キャッチャー
---------------------------------------------
名前:高坂
背番号:16
種類:キャッチャー
---------------------------------------------
名前:ゴメス
背番号:16
種類:キャッチャー
---------------------------------------------
名前:中村
背番号:6
種類:キャッチャー
---------------------------------------------
名前:春日井
背番号:32
種類:キャッチャー
---------------------------------------------
名前:堀田
背番号:5
種類:キャッチャー
---------------------------------------------
名前:逢坂
背番号:54
種類:キャッチャー
---------------------------------------------
名前:トーマス
背番号:11
種類:キャッチャー
---------------------------------------------
名前:斉藤
背番号:34
種類:ピッチャー