C2079エラーによってプログラムがコンパイルされない。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

C2079エラーによってプログラムがコンパイルされない。

#1

投稿記事 by keito94 » 7年前

アクションゲームを個人制作しているところですが、Main.cppの7行目くらいで、

コード:

C2079	'CGameMain::Player' が 未定義の class 'CPlayer' で使用しています。	
というエラーが出て困ってます。(また、様々なサイトを参考にキャラを左右に動かす程度のサンプルプログラムも制作しています。)

ソースコードは以下のとおりです。
Main.cpp

コード:

#include "Main.h"
#include "Player.h"
#include "Mapping.h"

CGameMain Main;
CFmfMap MapObj;

int CGameMain::MapLoad(const char* file_name, int stage_num) {
	MapBitCount = MapObj.GetLayerBitCount() == 8 ? 16 : 256;
	if (!MapObj.Open(file_name)) {
		return -1;
	}
	BYTE* layer = (BYTE*)MapObj.GetLayerCount();
	if (layer == NULL) {
		return -1;
	}
	return 0;
}

int CGameMain::Init() {
	ChangeWindowMode(TRUE), SetGraphMode(320, 240, 32);
	//DXライブラリの初期化エラーが発生したときに終了。
	if (DxLib_Init() == -1) { return -1; }
	Time = GetNowCount();
	new CPlayer(0.0F, 0.0F);
	SetDrawScreen(DX_SCREEN_BACK);
	SetWaitVSyncFlag(FALSE);
	Player.Init();
	return 0;
}

void CGameMain::Main() {
	Time = GetNowCount();
	//1/60秒立つまで待つ
	while(GetNowCount()-Time<1000/60){}
	Player.Update();
	Player.Draw();
}

void CGameMain::Fin() {
	Player.Fin();
	DxLib_End();
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	Main.Init();
	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
		Main.Main();
	}
	Main.Fin();
	return 0;
}
Main.h

コード:

#pragma once
#include "DxLib.h"
class CTaskList;
class CPlayer;
class CGameMain {
	int Time;
	CPlayer Player;
public:
	int MapLoad(const char* file_name, int stage_num);
	int Init();
	void Main();
	void Fin();
};
Task.h

コード:

#pragma once

class Task {
public:
	virtual ~Task() {}
	virtual void Initialize() {}     //初期化処理は実装してもしなくてもいい
	virtual void Finalize() {}     //終了処理は実装してもしなくてもいい
	virtual void Update() = 0;   //更新処理は必ず継承先で実装する
	virtual void Draw() = 0;   //描画処理は必ず継承先で実装する
};
CMover.h

コード:

#pragma once
class CMover {
public:
	float X, Y, L, R, T, B;
	float VX, VY;
	CMover() {};
	CMover(float x, float y, float l, float t, float r, float b);
	bool Hit(CMover* m);
};
Mover.cpp

コード:

#include "Dxlib.h"
#include "CharMove.h"
#include "Mover.h"
CMover::CMover(float x, float y, float l, float t, float r, float b)
	:X(x), Y(y), L(l), T(t), R(r), B(b),VX(0.0F),VY(0.0F){
}

bool CMover::Hit(CMover* m) {
	return
		X + L < m->X + m->R && m->X + m->L < X + R &&
		Y + T < m->Y + m->B && m->Y + m->T < Y + B;
}
Mapping.h

コード:

#pragma once
#include "fmfmap.h"
extern CFmfMap MapObj;
extern int MapBitCount;
CharMove.h

コード:

#pragma once
//マップチップ
const int MapCell = 16;
class CCharMove {
	float Clx, Crx, Cty, Cby;
	POINT mPt[8];
	int ColType;
public:
	CCharMove() {};
	CCharMove(POINT pt[], float clx, float crx, float cty, float cby,int coltype);
	void Init();
	POINT CheckMap(int x, int y);
	void MapDraw();
};
CharMove.cpp

コード:

#include "DxLib.h"
#include "Main.h"
#include "CharMove.h"
#include "Mapping.h"

int MapBitCount;

CCharMove::CCharMove(POINT pt[], float clx, float crx, float cty, float cby, int coltype)
	: Clx(clx), Crx(crx), Cty(cty), Cby(cby),ColType(coltype)
{
	Init();
	for (int i = 0; i < 8; i++) {
		mPt[i].x = pt[i].x;
		mPt[i].y = pt[i].y;
	}
}

void CCharMove::Init() {
	ZeroMemory(mPt, sizeof(mPt));
}

POINT CCharMove::CheckMap(int x, int y) {
	POINT pt[] = {
		{ x + mPt[0].x,	y + mPt[0].y },//左上
		{ x + mPt[1].x,	y + mPt[1].y },//上真ん中
		{ x + mPt[2].x,	y + mPt[2].y },//右上

		{ x + mPt[3].x,	y + mPt[3].y },//左真ん中
		{ x + mPt[4].x,	y + mPt[4].y },//右真ん中

		{ x + mPt[5].x,	y + mPt[5].y },//左下
		{ x + mPt[6].x,	y + mPt[6].y },//下真ん中
		{ x + mPt[7].x,	y + mPt[7].y },//右下
	};
	POINT res = { x, y };
	DWORD cwidth = MapObj.GetChipWidth();
	DWORD cheight = MapObj.GetChipHeight();

	for (int i = 0; i < 8; i++) {
		int index = MapObj.GetValue(1, pt[i].x / MapCell, pt[i].y / MapCell);
		int src_x = (index % MapBitCount) * cwidth;
		int src_y = (index / MapBitCount) * cheight;
		if (src_x == 0 && src_y == 0) // 取得したindexが壁だったら
		{
			res.x = pt[i].x / MapCell; // 壁の座標を代入
			res.y = pt[i].y / MapCell;
			return res; // 壁の座標を返す
		}
	}
	res.x = -1;
	res.y = -1;
	return res;
}

void CCharMove::MapDraw() {
	DWORD swidth = MapObj.GetMapWidth();
	DWORD sheight = MapObj.GetMapHeight();
	DWORD cwidth = MapObj.GetChipWidth();
	DWORD cheight = MapObj.GetChipHeight();
	DWORD i, j;
	int index, src_x, src_y;
	for (i = 0; i < sheight / MapCell; i++) {
		for (j = 0; j = swidth / MapCell; i++) {
			index = MapObj.GetValue(0, i, j);
			src_x = (index % MapBitCount) * cwidth;
			src_y = (index / MapBitCount) * cheight;
		}
	}
}
エラーログは以下の通りです。

コード:

1>Main.cpp
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.h(7): error C2079: 'CGameMain::Player' が 未定義の class 'CPlayer' で使用しています。
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.cpp(30): error C2228: '.Init' の左側はクラス、構造体、共用体でなければなりません
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.cpp(30): note: 型は 'int' です。
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.cpp(38): error C2228: '.Update' の左側はクラス、構造体、共用体でなければなりません
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.cpp(38): note: 型は 'int' です。
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.cpp(39): error C2228: '.Draw' の左側はクラス、構造体、共用体でなければなりません
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.cpp(39): note: 型は 'int' です。
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.cpp(43): error C2228: '.Fin' の左側はクラス、構造体、共用体でなければなりません
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.cpp(43): note: 型は 'int' です。
1>CharMove.cpp
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.h(7): error C2079: 'CGameMain::Player' が 未定義の class 'CPlayer' で使用しています。
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

アバター
durandal
記事: 11
登録日時: 7年前
住所: 長野県

Re: C2079エラーによってプログラムがコンパイルされない。

#2

投稿記事 by durandal » 7年前

クラス "CPlayer" がソース内で定義されていないことが原因だと思います。

YuO
記事: 947
登録日時: 13年前
住所: 東京都世田谷区

Re: C2079エラーによってプログラムがコンパイルされない。

#3

投稿記事 by YuO » 7年前

エラーメッセージの通りです。

Main.hの4行目にCPlayerクラスの宣言はありますが,7行目で定義を必要とするまでに,CPlayerクラスの定義がMain.h内には存在しません。
Main.hを利用する側でMain.hより前にCPlayerクラスの定義をしておけばコンパイル可能ですが,通常はMain.h内で定義がなされるようにします。

梅衣堂ひよ
記事: 24
登録日時: 7年前

Re: C2079エラーによってプログラムがコンパイルされない。

#4

投稿記事 by 梅衣堂ひよ » 7年前

クラスの前方宣言で利用できるのはポインタ型の宣言です。
実体を持つためにはサイズの割り当てのためにクラスの中身を知らないといけないため、利用する以前に前方宣言ではなくクラスの定義そのものが必要になります。
Main.h 7行目

コード:

CPlayer Player;
をポインタ型に変更し、InitでnewしてFinでdeleteすればいいと思います。

ちなみにこれはなんですか?
Main.cpp 25行目

コード:

new CPlayer(0.0F, 0.0F);
変数に割り当てていないためメモリリーク一直線なのですが…
結構説明が下手ですのでご了承ください。割と言葉が足りなかったり文字だらけで分かりにくかったりします。

アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

Re: C2079エラーによってプログラムがコンパイルされない。

#5

投稿記事 by keito94 » 7年前

梅衣堂さんの言うとおりにしたら以下のエラーコードが出ました。

コード:

1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\player.cpp(55): error C2541: 'delete': ポインターではないオブジェクトを削除することはできません。
どこに原因がありますか?
ソースコードでおもに変更した部分は以下のとおりです。

コード:

(省略)
void CPlayer::Init(void) {
	//画像を読み込む。
	X = 160.0F, Y = 240.0F;
	new CPlayer(X, Y);
	Graph = LoadGraph("テスト用.png");
	Dir = FALSE;
	Dash = FALSE;
}
(以下略)
void CPlayer::Fin(void) {
	//画像を削除する。
	DeleteGraph(Graph);
	delete CPlayer;
}
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

アバター
usao
記事: 1889
登録日時: 11年前

Re: C2079エラーによってプログラムがコンパイルされない。

#6

投稿記事 by usao » 7年前

オフトピック
> 梅衣堂さんの言うとおりにしたら以下のエラーコードが出ました。

エラーが出たのは他人のせい!みたいな文面に見えるが…


>InitでnewしてFinでdeleteすればいいと思います。

と言われたからといって,
わけもわからず,とりあえず "new" と "delete" という単語を打ち込めば良いわけではないと思いますが.
そんな状態で

>どこに原因がありますか?

とか問うのですか…

梅衣堂ひよ
記事: 24
登録日時: 7年前

Re: C2079エラーによってプログラムがコンパイルされない。

#7

投稿記事 by 梅衣堂ひよ » 7年前

どうやらポインタ型を知らないようなのでとりあえずポインタ型を調べることをお勧めします。
オフトピック
Main.hにPlayer.hをインクルードしてクラス内に実体を持つやり方でもいいですが、そのようなやり方だといずれクラスの相互参照によるコンパイルエラーになりかねません。
クラスが相互参照し、ヘッダーも相互参照するとなかなか気付くことができず、気付いても書き換えに時間のかかる面倒なコンパイルエラーを招きます。
これを避けるためにクラスの前方宣言とポインタ型を用いてヘッダーへのインクルードの必要をなくし、インクルードをヘッダーではなくソースファイルで行えるようにします。
それとnewとdeleteはCPlayerのInitとFinではなくCGameMainのInitとFinです
結構説明が下手ですのでご了承ください。割と言葉が足りなかったり文字だらけで分かりにくかったりします。

アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

Re: C2079エラーによってプログラムがコンパイルされない。

#8

投稿記事 by keito94 » 7年前

>InitでnewしてFinでdeleteすればいいと思います。

と言われたからといって,
わけもわからず,とりあえず "new" と "delete" という単語を打ち込めば良いわけではないと思いますが.
そんな状態で

>どこに原因がありますか?

とか問うのですか…
今思うと、ちょっと口悪かったかな…。反省してます…。
梅衣堂ひよ さんが書きました:どうやらポインタ型を知らないようなのでとりあえずポインタ型を調べることをお勧めします。
ポインタ型?関数のポインタのことだということは調べてみてわかったのですが…。具体的なコードを挙げてくれませんか?
また、このソースコードで間違っている点とかはありませんか?

コード:

#include "Main.h"
#include "Player.h"
#include "Mapping.h"

CGameMain Main;
CFmfMap MapObj;

int(*CPlayer)(float, float);

int CGameMain::MapLoad(const char* file_name, int stage_num) {
	MapBitCount = MapObj.GetLayerBitCount() == 8 ? 16 : 256;
	if (!MapObj.Open(file_name)) {
		return -1;
	}
	BYTE* layer = (BYTE*)MapObj.GetLayerCount();
	if (layer == NULL) {
		return -1;
	}
	return 0;
}

int CGameMain::Init() {
	ChangeWindowMode(TRUE), SetGraphMode(320, 240, 32);
	//DXライブラリの初期化エラーが発生したときに終了。
	if (DxLib_Init() == -1) { return -1; }
	Time = GetNowCount();
	SetDrawScreen(DX_SCREEN_BACK);
	SetWaitVSyncFlag(FALSE);
	int InitX = 0.0F, InitY = 0.0F;
	new *CPlayer(InitX,InitY);
	Player->Init();
	return 0;
}

void CGameMain::Main() {
	Time = GetNowCount();
	//1/60秒立つまで待つ
	while(GetNowCount()-Time<1000/60){}
	Player->Update();
	Player->Draw();
}

void CGameMain::Fin() {
	Player->Fin();
	delete (*CPlayer)(float,float);
	DxLib_End();
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	Main.Init();
	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
		Main.Main();
	}
	Main.Fin();
	return 0;
}
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

NNN

Re: C2079エラーによってプログラムがコンパイルされない。

#9

投稿記事 by NNN » 7年前

根本的な話ですが、何かしらの書籍なりサイトなりで言語学習した上で作成されているんでしょうか?
過去の質問を見ていると問題の原因をきちんと理解しないまま次へ次へと質問して基礎力が変わっていないように見受けられます。

例として挙げるのもあれですが過去にsamusu0905さんという方が色々な方にアドバイスを受け続けたにも関わらず
同じような質問を繰り返した結果数年経っても技術力がほとんど変わらないという形になってしまった方もいます。
今keito94さんは確実に同じ轍を踏もうとしています。

何かしらこんなものを作ってみたい、こんな風な技術者になりたいといった思いがあるのでしたら
一度自分が何を理解していないのか、何を学習すれば一歩進めるのかと深く考えてみると良いと思います。

アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

Re: C2079エラーによってプログラムがコンパイルされない。

#10

投稿記事 by keito94 » 7年前

NNN さんが書きました:根本的な話ですが、何かしらの書籍なりサイトなりで言語学習した上で作成されているんでしょうか?
過去の質問を見ていると問題の原因をきちんと理解しないまま次へ次へと質問して基礎力が変わっていないように見受けられます。
これは致命的だった!!質問は原因を理解して慎重にやらないとだめということですね…。
言語学習はしっかりしているつもりだったのですが…。
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

Re: C2079エラーによってプログラムがコンパイルされない。

#11

投稿記事 by keito94 » 7年前

ポインタ型というものをhttp://www7b.biglobe.ne.jp/~robe/cpphtm ... 03009.htmlで学んで、コードを以下の通りにしてみたのですが、

コード:

#include "Main.h"
#include "Player.h"
#include "Mapping.h"

CGameMain Main;
CFmfMap MapObj;
int Player;
float(*CPlayer)(float, float);

int CGameMain::MapLoad(const char* file_name, int stage_num) {
	MapBitCount = MapObj.GetLayerBitCount() == 8 ? 16 : 256;
	if (!MapObj.Open(file_name)) {
		return -1;
	}
	BYTE* layer = (BYTE*)MapObj.GetLayerCount();
	if (layer == NULL) {
		return -1;
	}
	return 0;
}

int CGameMain::Init() {
	ChangeWindowMode(TRUE), SetGraphMode(320, 240, 32);
	//DXライブラリの初期化エラーが発生したときに終了。
	if (DxLib_Init() == -1) { return -1; }
	Time = GetNowCount();
	SetDrawScreen(DX_SCREEN_BACK);
	SetWaitVSyncFlag(FALSE);
	int InitX = 0.0F, InitY = 0.0F;
	new *CPlayer(InitX,InitY);
	Player->Init();
	return 0;
}

void CGameMain::Main() {
	Time = GetNowCount();
	//1/60秒立つまで待つ
	while(GetNowCount()-Time<1000/60){}
	Player->Update();
	Player->Draw();
}

void CGameMain::Fin() {
	Player->Fin();
	delete (*CPlayer);
	DxLib_End();
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	Main.Init();
	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
		Main.Main();
	}
	Main.Fin();
	return 0;
}
以下のようなエラーコードを吐いてしまいました。

コード:

1>Main.cpp
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.cpp(31): warning C4244: '初期化中': 'float' から 'int' への変換です。データが失われる可能性があります。
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.cpp(32): error C2059: 構文エラー: '*'
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.cpp(32): warning C4244: '引数': 'int' から 'float' への変換です。データが失われる可能性があります。
1>c:\users\keito940\documents\visual studio 2017\projects\スタアド\スタアド\main.cpp(47): error C2541: 'delete': ポインターではないオブジェクトを削除することはできません。
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

Re: C2079エラーによってプログラムがコンパイルされない。

#12

投稿記事 by keito94 » 7年前

あっ、宣言したそばから質問してしまった!!!!
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

アバター
沖 滉均
記事: 237
登録日時: 13年前
住所: K県F市

Re: C2079エラーによってプログラムがコンパイルされない。

#13

投稿記事 by 沖 滉均 » 7年前

keito94 さんが書きました: ポインタ型?関数のポインタのことだということは調べてみてわかったのですが…。
一体どこからそのような話になったのでしょう?
usao さんが書きました:わけもわからず,とりあえず "new" と "delete" という単語を打ち込めば良いわけではないと思いますが.
この辺りのコメントと同じことを繰り返しているだけですよ。
検索してみたらたまたま関数ポインタという文字が引っかかった、ポインタって書いてあるからこれだろう
だからとりあえず意味はわからないけど書いてみた
意味を理解しようとしない限り答えを教えてもらって直してを繰り返してエラーがなくなっても自身で解決する力は付きませんよ?
オフトピック
口が悪いだのなんだのの前にエラーコード及びエラーの原因が書かれているのですから
まずは調べてみようとは思いませんか?
調べてわからないことを聞いたほうが覚えると思うのだけど
There is no royal road to learning.
codeタグで指定できる言語
画像

アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

Re: C2079エラーによってプログラムがコンパイルされない。

#14

投稿記事 by keito94 » 7年前

沖 滉均 さんが書きました: この辺りのコメントと同じことを繰り返しているだけですよ。
検索してみたらたまたま関数ポインタという文字が引っかかった、ポインタって書いてあるからこれだろう
だからとりあえず意味はわからないけど書いてみた
意味を理解しようとしない限り答えを教えてもらって直してを繰り返してエラーがなくなっても自身で解決する力は付きませんよ?
あっ、ごめんなさい!!
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

Re: C2079エラーによってプログラムがコンパイルされない。

#15

投稿記事 by keito94 » 7年前

ポインタ型についてしっかり調べなおしてきました。そういうことだったんですね…。
今度からエラーの一件はしっかり調べてみようと思います…。
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

返信

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