ページ 1 / 1
基底クラスの必要性について
Posted: 2017年3月14日(火) 22:50
by ryt
こんにちは
今年高専二年生になるものです。
http://dixq.net/g/sp_06.html
今回この記事について疑問に思ったことがあります。
Taskクラスを基底クラスとして、と書いてありますが、このTaskクラスの存在理由が今一つわからず質問させていただきました。
このTaskクラスがあってもなくても別段変わらないように思います。
勉強不足は重々承知ですが、どうかご回答宜しくお願い致します。
Re: 基底クラスの必要性について
Posted: 2017年3月14日(火) 23:20
by inemaru
Taskクラスを継承しているクラスは、Taskクラスとして扱えるため
配列にまとめるなどして処理しやすい利点があったり、
Taskクラスに定義されているメソッドが存在することが保証できたりする。
とかでしょうか。
Re: 基底クラスの必要性について
Posted: 2017年3月15日(水) 00:27
by purin52002
基底クラスってなんやねん。
そう思っていた時期が僕にもありました。
基底クラスってとても便利なんです。
inemaruさんもおっしゃる通り配列にまとめることができるんです。
このようなクラスがあったときに
コード:
class Base
{
public:
virtual void func(){ cout << "base" << endl; }
};
class A:public Base
{
public:
void func(){ cout << "A" << endl; }
};
class B:public Base
{
public:
void func(){ cout << "B" << endl; }
}
こんなことができます。
コード:
int main()
{
//基底クラスのポインタに継承クラスのポインタを代入することができる。
Base* objs[3]={ new Base(), new A(), new B() };
for(int i = 0; i < 3; ++i) objs[i]->func();//Base A B と表示
}
こんなこともできます。
コード:
int main()
{
Base* obj;
int i;
cin << i;
if(i==0) obj=new Base();
else obj=new A();
obj->func();
}
こんなことができてどうだっていうんだ、と思われるかもしれませんが、
プログラムの規模が大きくなってくると
「このコード、似たようなのを前に書いたなー」
「なんか似たような処理してんなー」
なんてことが出てきます。
その時に継承のありがたみが出てくるかもしれません。
しかも管理もしやすくなります。
A::funcの動作を変えたいときはA::funcを書き換えるだけで、他をいじる必要はありません。
また、新たにCクラスを作った場合、Baseを継承してさえいればmain文でCクラスを宣言するだけで他をいじる必要がありません。
今回の場合だとTaskクラスを継承していて、UpDate、Drawを定義したクラスであれば、SceneMgr::Updateのswitch内でnewしてやるだけで、他はいじらずに新たな機能を追加できます。
Re: 基底クラスの必要性について
Posted: 2017年3月15日(水) 00:49
by ryt
inemaruさんpurin52002さん、ご返信ありがとうございます。
纏めることができるのは確かにすごく便利です。
クラスが増えても継承さえしていれば、書き直す箇所が少なくなることも確かに利点だと思います。
しかしながら今回私が質問させていただいた理由は、Taskクラスでなく、BaseSceneでまとめていたからです。
それとも、このシーン管理以外のクラス(例えばPlayerやEnemyクラス)で使うためにあるのでしょうか。
先ほどの質問が曖昧だったために誤解を生んでしまい、申し訳ありませんでした。
ご回答よろしくお願いいたします。
Re: 基底クラスの必要性について
Posted: 2017年3月15日(水) 05:19
by へにっくす
ryt さんが書きました:しかしながら今回私が質問させていただいた理由は、Taskクラスでなく、BaseSceneでまとめていたからです。
TaskクラスはSceneMgrとBaseSceneをまとめてますよね?
それだけじゃ存在理由にならんのでしょうか。
あなたが示されたリンク先には、
SceneMgr、Game、Menu、Configはすべて「Initialize、Finalize、Update、Draw」という共通のメソッドを持っていました。
そこで、「Task」というすべてのクラスの元となる基底クラスを作ります。
さらに、Game,Menu,Configは同じ操作が重複していました。
そこで、「BaseScene」というシーンの抽象クラスを作ります。
と書かれています。存在理由はこれだけですよ?
Taskにまとめる理由が見つからないと思うなら、使わなきゃいいだけです。
Re: 基底クラスの必要性について
Posted: 2017年3月15日(水) 09:49
by usao
オフトピック
>このTaskクラスがあってもなくても別段変わらないように思います。
>しかしながら今回私が質問させていただいた理由は、Taskクラスでなく、BaseSceneでまとめていたからです。
そのリンク先を斜め読みした感じでは,
「{Game,Menu,Config}を BaseScene なるインタフェースでまとめるとシーン管理処理が {楽に(?), うまく(?)} 書ける」
的な説明が成されていて,確かにTaskクラスの存在意義は曖昧な感じはありますね.
纏めたい対象を"Taskとして"扱う部分がそのページのコード内には存在していないようなので,
リンク先ページの内容に限定して言えば,
・「SceneMgrが,BaseSceneを使ってシーン管理する」という話には,BaseSceneのさらなる基底としてTaskを用意する必要性はない
・SeceneMgrまでもがTaskを継承することにも利点は無い
と読めますね.
Taskが何かしらの共通処理の実装を解決しているわけでもないし.
(Initialize()とFInalize()の「何もしない」実装を提供してはいるが,BaseSceneもSceneMgrもそれを活用してはいない)
…なので,
>Taskにまとめる理由が見つからないと思うなら、使わなきゃいいだけです。
で良いと思います.
(Taskを継承する事の利点(例えばこういうふうに書いたりできますよ,とか)が存在するのだとしても,
「その利点の恩恵を受けないのであれば」不要.)
Re: 基底クラスの必要性について
Posted: 2017年3月15日(水) 14:43
by ryt
へにっくすさんusanoさん、ご返信ありがとうございます。
へにっくす さんが書きました:
TaskクラスはSceneMgrとBaseSceneをまとめてますよね?
それだけじゃ存在理由にならんのでしょうか。
Taskにまとめる理由が見つからないと思うなら、使わなきゃいいだけです。
そうですよね。Taskクラスは見たままの役割ですよね。
私は明確な存在価値を見いだせないことに、納得できなかっただけなのかもしれません。
usao さんが書きました:
リンク先ページの内容に限定して言えば,
・「SceneMgrが,BaseSceneを使ってシーン管理する」という話には,BaseSceneのさらなる基底としてTaskを用意する必要性はない
・SeceneMgrまでもがTaskを継承することにも利点は無い
と読めますね.
Taskが何かしらの共通処理の実装を解決しているわけでもないし.
(Initialize()とFInalize()の「何もしない」実装を提供してはいるが,BaseSceneもSceneMgrもそれを活用してはいない)
…なので,
>Taskにまとめる理由が見つからないと思うなら、使わなきゃいいだけです。
で良いと思います.
(Taskを継承する事の利点(例えばこういうふうに書いたりできますよ,とか)が存在するのだとしても,
「その利点の恩恵を受けないのであれば」不要.)
そこです。私の疑問を明確に解決してくださり、ありがとうございます。
お二方のおかげで、納得することができました。
ご返信していただいた皆様方、ありがとうございました。