合計 昨日 今日

基底クラスの必要性について

[このトピックは解決済みです]

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: ryt
[URL]
Date: 2017年3月14日(火) 22:50
No: 1
(OFFLINE)

 基底クラスの必要性について

こんにちは
今年高専二年生になるものです。

http://dixq.net/g/sp_06.html
今回この記事について疑問に思ったことがあります。
Taskクラスを基底クラスとして、と書いてありますが、このTaskクラスの存在理由が今一つわからず質問させていただきました。
このTaskクラスがあってもなくても別段変わらないように思います。

勉強不足は重々承知ですが、どうかご回答宜しくお願い致します。

Name: inemaru
[URL]
上級者(16,923 ポイント)
Date: 2017年3月14日(火) 23:20
No: 2
(OFFLINE)

 Re: 基底クラスの必要性について

Taskクラスを継承しているクラスは、Taskクラスとして扱えるため
配列にまとめるなどして処理しやすい利点があったり、
Taskクラスに定義されているメソッドが存在することが保証できたりする。

とかでしょうか。

Name: purin52002
[URL]
プログラマー(26,267 ポイント)
Date: 2017年3月15日(水) 00:27
No: 3
(OFFLINE)

 Re: 基底クラスの必要性について

基底クラスってなんやねん。
そう思っていた時期が僕にもありました。

基底クラスってとても便利なんです。
inemaruさんもおっしゃる通り配列にまとめることができるんです。

このようなクラスがあったときに
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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; }
}


こんなことができます。
コード[C++]: 全て選択
1
2
3
4
5
6
int main()
{
    //基底クラスのポインタに継承クラスのポインタを代入することができる。
    Base* objs[3]={ new Base(), new A(), new B() };
    for(int i = 0; i < 3; ++i) objs[i]->func();//Base A B と表示
}


こんなこともできます。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
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してやるだけで、他はいじらずに新たな機能を追加できます。
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

Name: ryt
[URL]
ぴよぴよ(327 ポイント)
Date: 2017年3月15日(水) 00:49
No: 4
(OFFLINE)

 Re: 基底クラスの必要性について

inemaruさんpurin52002さん、ご返信ありがとうございます。

纏めることができるのは確かにすごく便利です。
クラスが増えても継承さえしていれば、書き直す箇所が少なくなることも確かに利点だと思います。

しかしながら今回私が質問させていただいた理由は、Taskクラスでなく、BaseSceneでまとめていたからです。
それとも、このシーン管理以外のクラス(例えばPlayerやEnemyクラス)で使うためにあるのでしょうか。

先ほどの質問が曖昧だったために誤解を生んでしまい、申し訳ありませんでした。
ご回答よろしくお願いいたします。

Name: へにっくす
[URL]
熟練のプログラマー(61,211 ポイント)
Date: 2017年3月15日(水) 05:19
No: 5
(OFFLINE)

 Re: 基底クラスの必要性について

ryt さんが書きました:しかしながら今回私が質問させていただいた理由は、Taskクラスでなく、BaseSceneでまとめていたからです。

TaskクラスはSceneMgrとBaseSceneをまとめてますよね?
それだけじゃ存在理由にならんのでしょうか。

あなたが示されたリンク先には、
SceneMgr、Game、Menu、Configはすべて「Initialize、Finalize、Update、Draw」という共通のメソッドを持っていました。
そこで、「Task」というすべてのクラスの元となる基底クラスを作ります。
さらに、Game,Menu,Configは同じ操作が重複していました。
そこで、「BaseScene」というシーンの抽象クラスを作ります。

と書かれています。存在理由はこれだけですよ?

Taskにまとめる理由が見つからないと思うなら、使わなきゃいいだけです。
written by へにっくす

Name: usao
[URL]
ハッカー(138,194 ポイント)
Date: 2017年3月15日(水) 09:49
No: 6
(OFFLINE)

 Re: 基底クラスの必要性について

Offtopic :
>このTaskクラスがあってもなくても別段変わらないように思います。

>しかしながら今回私が質問させていただいた理由は、Taskクラスでなく、BaseSceneでまとめていたからです。

そのリンク先を斜め読みした感じでは,
「{Game,Menu,Config}を BaseScene なるインタフェースでまとめるとシーン管理処理が {楽に(?), うまく(?)} 書ける」
的な説明が成されていて,確かにTaskクラスの存在意義は曖昧な感じはありますね.


纏めたい対象を"Taskとして"扱う部分がそのページのコード内には存在していないようなので,
リンク先ページの内容に限定して言えば,

・「SceneMgrが,BaseSceneを使ってシーン管理する」という話には,BaseSceneのさらなる基底としてTaskを用意する必要性はない
・SeceneMgrまでもがTaskを継承することにも利点は無い

と読めますね.

Taskが何かしらの共通処理の実装を解決しているわけでもないし.
(Initialize()とFInalize()の「何もしない」実装を提供してはいるが,BaseSceneもSceneMgrもそれを活用してはいない)


…なので,

>Taskにまとめる理由が見つからないと思うなら、使わなきゃいいだけです。

で良いと思います.
(Taskを継承する事の利点(例えばこういうふうに書いたりできますよ,とか)が存在するのだとしても,
 「その利点の恩恵を受けないのであれば」不要.)

Name: ryt
[URL]
ぴよぴよ(327 ポイント)
Date: 2017年3月15日(水) 14:43
No: 7
(OFFLINE)

 Re: 基底クラスの必要性について

[解決!]

へにっくすさんusanoさん、ご返信ありがとうございます。


へにっくす さんが書きました:TaskクラスはSceneMgrとBaseSceneをまとめてますよね?
それだけじゃ存在理由にならんのでしょうか。

Taskにまとめる理由が見つからないと思うなら、使わなきゃいいだけです。

そうですよね。Taskクラスは見たままの役割ですよね。
私は明確な存在価値を見いだせないことに、納得できなかっただけなのかもしれません。


usao さんが書きました:リンク先ページの内容に限定して言えば,

・「SceneMgrが,BaseSceneを使ってシーン管理する」という話には,BaseSceneのさらなる基底としてTaskを用意する必要性はない
・SeceneMgrまでもがTaskを継承することにも利点は無い

と読めますね.

Taskが何かしらの共通処理の実装を解決しているわけでもないし.
(Initialize()とFInalize()の「何もしない」実装を提供してはいるが,BaseSceneもSceneMgrもそれを活用してはいない)

…なので,

>Taskにまとめる理由が見つからないと思うなら、使わなきゃいいだけです。

で良いと思います.
(Taskを継承する事の利点(例えばこういうふうに書いたりできますよ,とか)が存在するのだとしても,
 「その利点の恩恵を受けないのであれば」不要.)

そこです。私の疑問を明確に解決してくださり、ありがとうございます。
お二方のおかげで、納得することができました。


ご返信していただいた皆様方、ありがとうございました。


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[9人]