オーバーライドができない

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
M

オーバーライドができない

#1

投稿記事 by M » 16年前

ヘッダを勉強しなおしている、初心者プログラマーですが、
オーバーライドができない理由が分からず、こまっていたところです。

ここにコードを記します。
//main.cpp
#include "commonInclude.h"
#include"cat.h"
#include"fatCat.h"
int main()
{
	cat cat1 = cat("1stCat");
	cat1.naku();
	
	cat cat2 = fatCat(23);
	cat2.naku();
}

//commonInclude.h
#include <iostream>
#include <string>
using namespace std;


//cat.h
#ifndef catIncluded
#define catIncluded
#include "commonInclude.h"

class cat
{
protected:
    string name;
public:
	cat();
    cat(string);
    virtual void naku();
};
#endif


//cat.cpp
#include "cat.h"
cat::cat(){
	name = "ななし";
}
cat::cat(string s){
	name = s;
}
void cat::naku(){
        cout<<"おいらの名前は"<<name<<"だ。"<<endl;
}

//fatCat.h
#ifndef fatCatIncluded
#define fatCatIncluded
#include "commonInclude.h"
#include "cat.h"
class fatCat : public cat{
	int weight;
public:
    fatCat(int);
	void naku();
};
#endif


//fatCat.cpp
#include "fatCat.h"
fatCat::fatCat(int num){
	weight = num;
	name = "ななし";
}
void fatCat::naku()
{
        cout<<"おいらは太っている、"<<name<<"だ。"<< endl;
	cout << "体重は"<< weight << "だ。" <<endl;
}

この実行時に、

おいらの名前は1stCatだ。
おいらは太っている、ななしだ。
体重は23だ。

と表示したいところが、

おいらの名前は1stCatだ。
おいらの名前はななしだ。

と表示されてしまいます。
原因と解決法を教えてください<(_ _)>

SCI

Re:オーバーライドができない

#2

投稿記事 by SCI » 16年前


//main.cpp
#include "commonInclude.h"
#include "cat.h"
#include "fatCat.h"

int main()
{
cat cat1 = cat("1stCat");
cat1.naku();

cat cat2 = fatCat(23);
cat2.naku();
}

赤字の部分を見てください。(以下、正確な説明じゃないかもしれませんが・・・)
catクラスのインスタンスをfatCatで初期化しています。
すると、実行されるメソッドは「catクラス」のものになります。
fatCatに書き直すか、初期化の書き方を別のやり方にして混乱をなくす方法が考えられます。

SCI

Re:オーバーライドができない

#3

投稿記事 by SCI » 16年前

>fatCatに書き直すか、初期化の書き方を別のやり方にして混乱をなくす方法が考えられます。

変な書き方をしてしまいました。。fatCatに書き直すのは必須ですね。特殊なやり方があるのかもしれませんが・・・

M

Re:オーバーライドができない

#4

投稿記事 by M » 16年前

そういえば、そうでしたっけ。。。

すいません、説明が足りませんでした。
クラスCatは将来的には、様々な種類の猫(継承したもの)を、配列にいれて、すべて適切に鳴かせるために作っています。

つまり
Cat myCats[10];
Cat cat1 = Cat("1stCat");
fatCat cat2 = fatCat(23);
myCats[0] = cat1;
myCats[1] = cat2;
//続く…

for(int i = 0; i < 10; i++){
	myCats.naku();
}



このような実行をした時に、どんな種類の猫でも適切に鳴いて欲しいわけです。
たしか、これを実現するのが仮想関数(virtual)で、合ってると思ったのですが・・・。

これを実行すれば、

おいらの名前は1stCatだ。
おいらは太っている、ななしだ。
体重は23だ。

と出力すると期待していたのですが、、、

おいらの名前は1stCatだ。
おいらの名前はななしだ。

になるんです;;

組木紙織

Re:オーバーライドができない

#5

投稿記事 by 組木紙織 » 16年前

>クラスCatは将来的には、様々な種類の猫(継承したもの)を、配列にいれて、すべて適切に鳴かせるために作っています。

だーめーそれはやっちゃだめです。


基底クラスの配列に継承されたクラスを入れて扱うことはC++ではやっちゃだめなことです。
するのなら、基底クラスのポインタを利用してください
boostにそのような用途で使えるクラスがあったとような記憶がありますが、

<参考文献>
more effective C++ 項目3:配列をポリモルフィズム的に扱ってはいけない参照

以下サンプルコード
#include <iostream>

class Hoge
{
private:
	int num;
public:
	int get()
	{
		return num;
	}
	virtual void print()
	{
		std::cout << "Hoge " << get() << std::endl;
	}
	Hoge(int a)
	:num(a)
	{
	}
};


class B: public Hoge
{
public:
	virtual void print()
	{
		std::cout << "B :"  << get() << std::endl;
	}
	B(int a):Hoge(a){}
};


int main()
{
	Hoge * hoges[10];
	hoges[0] = new Hoge(3);
	hoges[1] = new B(3);
	
	for(int i=0;i<2;i++){
		hoges->print();
	}
	
	for(int i=0;i<2;i++){
		delete hoges;
	}	

	return 0;
}

M

Re:オーバーライドができない

#6

投稿記事 by M » 16年前

おおお!なるほど!ポインタじゃないとだめだったのですね。
助かりました!!
ありがとうございます!

閉鎖

“C言語何でも質問掲示板” へ戻る