引数付きのコンストラクタについて...

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
onehst
記事: 14
登録日時: 9年前
住所: 東京都

引数付きのコンストラクタについて...

#1

投稿記事 by onehst » 9年前

連日の初歩的な質問をお許しください。

クラスを作成していたところ引数つきのコンストラクタを定義したら次のような
エラーが吐かれてしまいました。なお2Dでフィールドに文字をちりばめて
ひとつの単語(もしくは曲名や人物など)にするというゲームです。なので単語を1文字1文字に分けて
ランダムにフィールドに表示する・・・・・といったところで詰まっています

1>c:\users\------\desktop\gameprog2\gameprog2\class.h(60) : error C2146: 構文エラー : ')' が、識別子 'Input' の前に必要です。
1>c:\users\------\desktop\gameprog2\gameprog2\class.h(60) : error C3646: 'Input' : 不明なオーバーライド指定子です
1>c:\users\------\desktop\gameprog2\gameprog2\class.h(60) : error C2059: 構文エラー : ')'
1>c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(88) : error C2059: 構文エラー : ')'
1>c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(90) : error C2065: 'Input' : 定義されていない識別子です。
1>c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(90) : error C2070: ''unknown-type'': sizeof オペランドが正しくありません。
1>c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(93) : error C2065: 'Input' : 定義されていない識別子です。
1>c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(93) : error C2070: ''unknown-type'': sizeof オペランドが正しくありません。
1>c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(94) : error C2065: 'Input' : 定義されていない識別子です。
1>c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(102) : error C2143: 構文エラー : ')' が '{' の前にありません。
1>c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(111) : error C2440: '=' : 'int *' から 'int [20]' に変換できません。
1> 配列型への変換はありませんが、参照またはポインタから配列への変換があります。
1>c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(112) : error C2440: '=' : 'int *' から 'int [20]' に変換できません。
1> 配列型への変換はありませんが、参照またはポインタから配列への変換があります。
1>c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(115) : error C2601: 'Mozi::answerPutmap' : ローカル関数の定義が正しくありません。
1> c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(88): この行は '{' を含んでいますが、これに対応するものがありません。
1>c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(130) : fatal error C1075: 左側 中かっこ '{' に対応するものが 'c:\users\kazuki\desktop\gameprog2\gameprog2\class.cpp(88)' で見つかる前に EOF が検出されました。


//Class.h
class Mozi{
public:
char answer[20]; //答え
int x[20],y[20]; //座標
int point; //正解した時に入る得点
int scope; //文字の当たり範囲
int Random_X[20],Random_Y[20]; //文字の位置のrandomの数を入れる
bool InputFlag; //文字をダブらず配置させるためのフラグ
Mozi(char[] Input); //コンストラクタ
void answerPutmap(int Time); //答えのピースをちりばめる
//bool answercheck(); //答えがあっているかを確認する(未実装)

};
//------------------------------Class.h終わり---------------------------------------
//Class.cpp
Mozi::Mozi(char[] Input){

point=2*sizeof(Input);
scope=6; //文字の当たり範囲は6

for(int i=0;i<sizeof(Input);i++){
answer=Input; //文字をいれていく
InputFlag=true;

//文字の位置をかぶらないようにしたい・・・・・・・・・・・・・・
while(InputFlag){
Random_X=GetRand(290)+20; //文字の位置をRandomにとる
Random_Y=GetRand(270)+20;
for(int j=0;j<i;j++){
if(abs(Random_X-Random_X[j])>20 && abs(Random_Y-Random_Y[j]<20){ //ほかの文字との距離感が程よい位置になったら
if(j==i-1) InputFlag=false; //全部程よい位置ならそこで確定する
}else{
break;
}

}//for(int j=0;j<i;j++)
}//while(InputFlag)

x=Random_X+40;
y=Random_Y+40;

}
void Mozi::answerPutmap(int Time){
extern int image[30];
static int English[sizeof(answer)];

for(int i=0;i<sizeof(answer);i++){

if(answer>90){
English=answer-97; //小文字のとき
}else{
English=answer[i]-65; //大文字のとき
}

DrawRotaGraph(x,y+8*(sin(PI*(Time+3*i)/30)+1)/2,1.5f,0.0f,image[English[i]],TRUE);
}
}
//----------------------------class.cpp終わり-----------------------------------------
//draw.cpp(描画を行なう部分の関連がありそうなところのみ)
//文字を描画する
void Mozidraw(int Time){

Mozi mozi("FLOWER");
mozi.answerPutmap(Time);
}
//draw.cpp終わり

以上となります。長文になってしまい申し訳ありません.....
どなたか原因と解決策をご教授していただけると大変助かります。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 引数付きのコンストラクタについて...

#2

投稿記事 by みけCAT » 9年前

ソースコードを提示する際は、BBCodeを有効にした(無効にしない)状態でBBCodeのcodeタグで囲んでいただけると、見やすくてありがたいです。

明らかに提示された行番号が提示されたソースコードと一致していないので、こちらでこのtougou.cppをコンパイルした結果のエラーについて対処します。
tougou.cpp

コード:

int GetRand(int){return 0;}
int abs(int){return 0;}
#include "Class.h"
#include "Class.cpp"
#include "draw.cpp"
オフトピック
あくまでこれは簡単に検証するためのものであり、普段はcppファイルをインクルードするべきではありません。

コード:

In file included from tougou.cpp:3:0:
Class.h:9:19: error: expected ',' or '...' before 'Input'
       Mozi(char[] Input); //コンストラクタ
                   ^
In file included from tougou.cpp:4:0:
Class.cpp:1:19: error: expected ',' or '...' before 'Input'
 Mozi::Mozi(char[] Input){
引数Inputの宣言がおかしいです。
C++で配列(引数においてはポインタとなるが)を宣言するには、char[] Inputではなくchar Input[]です。

コード:

Class.cpp: In constructor 'Mozi::Mozi(char*)':
Class.cpp:3:17: error: 'Input' was not declared in this scope
  point=2*sizeof(Input);
上記の間違いにより、Inputが認識されていません。

コード:

Class.cpp:15:75: error: expected ')' before '{' token
      if(abs(Random_X[i]-Random_X[j])>20 && abs(Random_Y[i]-Random_Y[j]<20){ //
ほかの文字との距離感が程よい位置になったら
                                                                           ^
2番目のabs関数を呼び出す時の閉じカッコが抜けています。

コード:

Class.cpp:21:5: error: expected primary-expression before '}' token
     }//for(int j=0;j<i;j++)
     ^
Class.cpp:21:5: error: expected ';' before '}' token
上記の間違いにより、コンパイラが混乱しているようです。

コード:

Class.cpp:24:3: error: incompatible types in assignment of 'int*' to 'int [20]'
  x=Random_X+40;
   ^
Class.cpp:25:3: error: incompatible types in assignment of 'int*' to 'int [20]'
  y=Random_Y+40;
C++では配列への直接代入はできません。
ループを用いて要素を一つずつ代入するといいでしょう。
【訂正】

コード:

x[i]=Random_X[i]+40;
y[i]=Random_Y[i]+40;
とするといいでしょう。

コード:

Class.cpp:28:35: error: a function-definition is not allowed here before '{' tok
en
 void  Mozi::answerPutmap(int Time){
                                   ^
In file included from tougou.cpp:5:0:
draw.cpp:5:2: error: expected '}' at end of input
  }
  ^
Class.cppの6行目のfor文「for(int i=0;i<sizeof(Input);i++){」の終わりの閉じカッコが抜けています。
最後に編集したユーザー みけCAT on 2016年8月20日(土) 00:44 [ 編集 1 回目 ]
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 引数付きのコンストラクタについて...

#3

投稿記事 by みけCAT » 9年前

また、Mozi::Moziの引数をchar Input[]にした場合、sizeof(Input)は文字列の長さなどではなく、Inputのサイズ、すなわちchar*のサイズになります。
その結果、処理されるべきデータが処理されなかったり、逆に範囲外にアクセスして未定義動作を起こす可能性があります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 引数付きのコンストラクタについて...

#4

投稿記事 by みけCAT » 9年前

Mozi::answerPutmapの実装もまずそうですね。
例えば6文字の文字列がanswerに入っている状態でこの関数を呼び出すと、sizeof(answer)は20なので、6番目(0-origin)のナル文字についてもループ内の処理が行われます。
すると、0は90より大きくないので、English[6]=-65となり、この値を用いてimage[English[6]]の計算をすることになりますが、
これは範囲外へのアクセスであり、未定義動作となります。
従って、何も考えず配列全体を処理するのではなく、文字列の終端で処理を止めないといけません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 引数付きのコンストラクタについて...

#5

投稿記事 by みけCAT » 9年前

オフトピック
そもそも、Random_X、Random_Y、Englishは配列にせず、普通のint型の変数として確保してそれぞれの繰り返しで使い回せばいいのでは?
何か他にこれらの保存した値を使う処理があるのだろうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

onehst
記事: 14
登録日時: 9年前
住所: 東京都

Re: 引数付きのコンストラクタについて...

#6

投稿記事 by onehst » 9年前

返信送れて申し訳ありません。
大変詳細な部分までご指摘してくださってありがとうございます。

>>>>ソースコードを提示する際は、BBCodeを有効にした(無効にしない)状態でBBCodeのcodeタグで囲んでいただけると、見やすくてありがたいです。
>>>>明らかに提示された行番号が提示されたソースコードと一致していないので、こちらでこのtougou.cppをコンパイルした結果のエラーについて対処します。


申し訳ありません。フォーラムルールをよく読まずに投稿をしていました。
今後はこのようなことがないように努めます。

また、みけCAT様のご指摘どおりにプログラムを修正したところ、エラーはなくなりましたが、

>>>また、Mozi::Moziの引数をchar Input[]にした場合、sizeof(Input)は文字列の長さなどではなく、Inputのサイズ、すなわちchar*のサイズになります。その結果、処理されるべきデータが処理されなかったり、逆に範囲外にアクセスして未定義動作を起こす可能性があります。

この誤りを訂正してないため、マップ上に文字が描画されませんでした。

>>>>Mozi::answerPutmapの実装もまずそうですね。
例えば6文字の文字列がanswerに入っている状態でこの関数を呼び出すと、sizeof(answer)は20なので、6番目(0-origin)のナル文字についてもループ内の処理が行われます。
すると、0は90より大きくないので、English[6]=-65となり、この値を用いてimage[English[6]]の計算をすることになりますが、これは範囲外へのアクセスであり、未定義動作となります。
従って、何も考えず配列全体を処理するのではなく、文字列の終端で処理を止めないといけません。
こちらの「文字列の終端で処理をとめる」と言う処理をするのは

コード:

for(int i=0;i<20;i++){

		if(Input[i]=='\0'){//ヌル文字がでてきたら
				
			num=i; break; //その数をnumにいれる
		}

	}
のようにnumというint型の変数をクラスのメンバにして、コンストラクタ内で上のようにヌル文字が出てきたときの
番号(6文字なら6)にいれてsizeof...と定義していたところをnumに変えて実行したところ
一先ずは解決いたしました。 ありがとうございました。

>>>
オフトピック
そもそも、Random_X、Random_Y、Englishは配列にせず、普通のint型の変数として確保してそれぞれの繰り返しで使い回せばいいのでは?
何か他にこれらの保存した値を使う処理があるのだろうか?
絶対値のところや当たり判定のときに使うつもりだったのですが....
よくよく考えてみれば、x,yに代入してるのでそちらの値と比較すればよいことですし、
Englishの方もご指摘のとおり使いまわしが出来そうです。ありがとうございます。

閉鎖

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