vector<*>の使い方がわからない

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

vector<*>の使い方がわからない

#1

投稿記事 by RockSuger » 2年前

コード:

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と表示されるかしかできないです。

RockSuger

Re: vector<*>の使い方がわからない

#2

投稿記事 by RockSuger » 2年前

すいません、&alyは&allyです。

かずま

Re: vector<*>の使い方がわからない

#3

投稿記事 by かずま » 2年前

RockSuger さんが書きました:すいません、&alyは&allyです。
いいえ、&aly と aly.set はそのままで、直前に
Ally aly; を追加してください。そうすると、
「Ally1Ally2」と表示されます。

ally 1個だけだと、ally.a に 1 と 2 を同時に持たせるのは無理です。

func()が"失敗"と表示されるプログラムを提示してください。

RockSuger

Re: vector<*>の使い方がわからない

#4

投稿記事 by RockSuger » 2年前

かずま さんが書きました:
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;
}

アバター
purin52002
記事: 235
登録日時: 2年前
連絡を取る:

Re: vector<*>の使い方がわからない

#5

投稿記事 by purin52002 » 2年前

ちょっと待った!

test型とAlly型は例え継承関係にあっても型は違うはず、、、。
よって代入はできないのではないしょうか!?

これでもくらえ!

コード:

test a;
std::vector<test> a_vec;
Ally b;

a = b;//たぶんエラー 
a_vec.push_back(b);//上がエラーになるならこれもエラーになるはず
今回のような場合で継承クラスを扱うにはポインタは必要不可欠だと思います。
よってvectorの中身の型はtest*のままでいいと思います^^

失敗を表示するにはAlly*型を代入するのではなく、test*型を代入すればいいと思いました^^
オフトピック
逆転裁判おもしろいけど難しい^p^
[hr]
追記:06/23
基底クラスに継承クラスを代入することは可能なようでした。

コード:

test a;
std::vector<test> a_vec;
Ally b;

a = b;//たぶんエラー 、、、ではなくちゃんとビルドできる
a_vec.push_back(b);//上がエラーになるならこれもエラーになるはず、、、これもビルドできる
最後に編集したユーザー purin52002 on 2017年6月23日(金) 22:38 [ 編集 1 回目 ]
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

maru
記事: 150
登録日時: 8年前

Re: vector<*>の使い方がわからない

#6

投稿記事 by maru » 2年前

ポインタの使い方がよくわかっていないようですね。

コード:

    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では警告すら出ない!

maru
記事: 150
登録日時: 8年前

Re: vector<*>の使い方がわからない

#7

投稿記事 by maru » 2年前

purin52002 さんが書きました:test型とAlly型は例え継承関係にあっても型は違うはず、、、。よって代入はできないのではないしょうか!?
規格にはどう書いてあるかよくわからないが、継承先オブジェクトを継承元に代入するのはOKでした(寝ぼけていたのかな?<自分)。
継承は元のメンバ+αなので継承先を元に代入すると、元のメンバのみコピーされ+αの部分がなくなる。逆はNG。
これは構造体でも同じですね。

アバター
purin52002
記事: 235
登録日時: 2年前
連絡を取る:

Re: vector<*>の使い方がわからない

#8

投稿記事 by purin52002 » 2年前

自分の無知っぷりを披露してしまいました^p^
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

RockSuger

Re: vector<*>の使い方がわからない

#9

投稿記事 by RockSuger » 2年前

初めての質問でここまで教えていただけると思っていませんでした!
教えていただいた かずまさん、purin52002さん、maruさん、本当にありがとうございましたー!
結果としてはnewで作っていく形が一番やりやすかったのでそれでいこうと思います。
また質問させていただくと思いますが、その時はよろしくお願いします!

返信

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