ページ 1 / 1
vector<*>の使い方がわからない
Posted: 2017年6月23日(金) 02:08
by RockSuger
コード:
class test
{
public:
virtual void func() { printf("失敗"); }
virtual void set(int num) { a = num; }
protected:
int a = 0;
};
class Ally : public test
{
public:
void func() { printf("Ally%d", a); }
};
コード:
int main()
{
std::vector<test*> vec;
Ally ally;
aly.set(1);
vec.push_back(&aly);
ally.set(2);
vec.push_back(&ally);
vec[0]->func();
vec[1]->func();
Sleep(2000);
return 0;
}
C++勉強して1年くらいです。
DXLIBを使ってキャラクターを不特定多数出現させて各々の動きをさせてみたいので、クラスを使い仮想関数を上書きしてユニークキャラを作ろうとしていたのですが、うまいこといきません。
継承元クラス自体にprotectedで位置情報、publicで動き関数をつけて継承元vectorをぐるぐる回せば何とかなるようにしてみたいのですが、どうすればいいでしょうか。
vectorは勝手にnew,deleteしてくれる便利屋さんという認識です。
今回vector<*>を初めて使うので教えていただきたいです。
よろしくお願いします。
[1] vector<継承元ポインタ>を使って継承先の関数、変数を使いたい。
[1.1] Ally1Ally2と表示したい
[1.3] func()が"失敗"と表示されるかAlly2Ally2と表示されるかしかできないです。
Re: vector<*>の使い方がわからない
Posted: 2017年6月23日(金) 02:09
by RockSuger
すいません、&alyは&allyです。
Re: vector<*>の使い方がわからない
Posted: 2017年6月23日(金) 04:14
by かずま
RockSuger さんが書きました:すいません、&alyは&allyです。
いいえ、&aly と aly.set はそのままで、直前に
Ally aly; を追加してください。そうすると、
「Ally1Ally2」と表示されます。
ally 1個だけだと、ally.a に 1 と 2 を同時に持たせるのは無理です。
func()が"失敗"と表示されるプログラムを提示してください。
Re: vector<*>の使い方がわからない
Posted: 2017年6月23日(金) 04:59
by RockSuger
かずま さんが書きました:RockSuger さんが書きました:すいません、&alyは&allyです。
いいえ、&aly と aly.set はそのままで、直前に
Ally aly; を追加してください。そうすると、
「Ally1Ally2」と表示されます。
ally 1個だけだと、ally.a に 1 と 2 を同時に持たせるのは無理です。
func()が"失敗"と表示されるプログラムを提示してください。
かずまさんありがとうございます!
先ほどもう少し調べてみると、newを使った方法も出てきました。
コード:
int main()
{
vector<test*> vec;
Ally aly;
vec.push_back(new Ally);
vec[0]->set(1);
vec.push_back(new Ally);
vec[1]->set(2);
vec[0]->func();
vec[1]->func();
Sleep(2000);
delete vec[0];
delete vec[1];
return 0;
}
このような形と教えていただいた形ではどちらのほうがいいのでしょうか?
ちなみに失敗が表示されるのはこちらです。
コード:
int main()
{
std::vector<test> vec;
Ally ally;
ally.set(1);
vec.push_back(ally);
ally.set(2);
vec.push_back(ally);
vec[0].func();
vec[1].func();
Sleep(2000);
return 0;
}
Re: vector<*>の使い方がわからない
Posted: 2017年6月23日(金) 08:06
by purin52002
ちょっと待った!
test型とAlly型は例え継承関係にあっても型は違うはず、、、。
よって代入はできないのではないしょうか!?
これでもくらえ!
コード:
test a;
std::vector<test> a_vec;
Ally b;
a = b;//たぶんエラー
a_vec.push_back(b);//上がエラーになるならこれもエラーになるはず
今回のような場合で継承クラスを扱うにはポインタは必要不可欠だと思います。
よってvectorの中身の型はtest*のままでいいと思います^^
失敗を表示するにはAlly*型を代入するのではなく、test*型を代入すればいいと思いました^^
[hr]
追記:06/23
基底クラスに継承クラスを代入することは可能なようでした。
コード:
test a;
std::vector<test> a_vec;
Ally b;
a = b;//たぶんエラー 、、、ではなくちゃんとビルドできる
a_vec.push_back(b);//上がエラーになるならこれもエラーになるはず、、、これもビルドできる
Re: vector<*>の使い方がわからない
Posted: 2017年6月23日(金) 08:18
by maru
ポインタの使い方がよくわかっていないようですね。
コード:
std::vector<test*> vec;
Ally ally;
ally.set(1);
vec.push_back(&ally);
ally.set(2);
vec.push_back(&ally);
このコードはAllyクラスの実体(オブジェクト)はallly一つでありそのポインタをベクタに二つ格納している。
そのポインタが指すオブジェクトはローカルに宣言されたallyであり、その値(a)は2になっている。
仮想関数func()の呼び出しでは[0],[1]どちらもallyの関数を呼び出すので"ally2ally2"と表示される。
> このような形と教えていただいた形ではどちらのほうがいいのでしょうか?
やりたいのは複数のオブジェクトを管理したいのであろうから、ローカル変数を使いまわすのではなく、
newを使ってオブジェクトを生成するのが正しい。
失敗が表示されるコードはベクタの要素をtest型(*がついていない!)としているため、Ally型のオブジェクトを
格納してもtestの関数が呼び出されてしまうため。
> test型とAlly型は例え継承関係にあっても型は違うはず、、、。
> よって代入はできないのではないしょうか!?
私もそう思ったんだけど、VC++2015では警告すら出ない!
Re: vector<*>の使い方がわからない
Posted: 2017年6月23日(金) 19:09
by maru
purin52002 さんが書きました:test型とAlly型は例え継承関係にあっても型は違うはず、、、。よって代入はできないのではないしょうか!?
規格にはどう書いてあるかよくわからないが、継承先オブジェクトを継承元に代入するのはOKでした(寝ぼけていたのかな?<自分)。
継承は元のメンバ+αなので継承先を元に代入すると、元のメンバのみコピーされ+αの部分がなくなる。逆はNG。
これは構造体でも同じですね。
Re: vector<*>の使い方がわからない
Posted: 2017年6月23日(金) 22:36
by purin52002
自分の無知っぷりを披露してしまいました^p^
Re: vector<*>の使い方がわからない
Posted: 2017年6月24日(土) 03:24
by RockSuger
初めての質問でここまで教えていただけると思っていませんでした!
教えていただいた かずまさん、purin52002さん、maruさん、本当にありがとうございましたー!
結果としてはnewで作っていく形が一番やりやすかったのでそれでいこうと思います。
また質問させていただくと思いますが、その時はよろしくお願いします!