クラス内での関数ポインタの使用について

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

クラス内での関数ポインタの使用について

#1

投稿記事 by north » 10年前

いつも質問に答えていただきありがとうございます。
現在、龍神録プログラミングの館を参考にSTGを作成しているのですが、第12章を参考に敵の行動パターンをいろいろと作成してみたのですが、
関数ポインタの部分で躓いております。
関数ポインタ事態を使うのが初めてで調べながらやってみたのですがヘッダーで定義した関数ポインタをcppファイルでどうやって使えばいいのかわからないです。
下記が自分なりに書いてみたコードです

Enemy.h

コード:

#ifndef ENEMYH
#define ENEMYH
//-----------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <iostream>
#include "DxLib.h"
#include <Math.h>
using namespace std;

#define ENEMY_MODEL_KIND (3)
#define ENEMY_MAX (30)
#define ENEMY_ORDER_MAX (500) //敵の出現情報最大数
#define ENEMY_MOVEX_MIN (252)
#define ENEMY_MOVEX_MAX (385)
#define ENEMY_MOVEZ_MIN (177)
#define ENEMY_MOVEZ_MAX (300)
#define ENEMY_PATTERN_MAX (11)
#define PI 3.1415926535898
#define PI2 (PI*2)
//------------------------------------------------------------

class CEnemy
{
public:
	//敵の情報の構造体
	typedef struct
	{
		int Flag;	//敵のフラグ
		int Count;	//敵のカウンター
		int Pattern;	//敵の移動パターン
		int Muki;	//敵の向き
		int Kind;	//敵の種類
		int Hp;		//敵のHP
		int MaxHp;	//敵の最大HP
		int Item_n[6];	//落とすアイテム
		int ModelHandle[ENEMY_MODEL_KIND];	//敵のモデルの格納ハンドル
		int Model;
		VECTOR Pos;	//敵の座標
		float VX;	//速度X成分
		float VZ;	//速度Z成分
		float Spd;	//スピード
		float Angle;	//角度
		int BulletTime;	//弾幕開始時間
		int BulletKind;	//弾幕の種類
		int BulletKind2;	//弾幕の種類
		int Color;	//色
		int State;	//状態
		int WaitTime;	//待機時間
		int Wait;	//停滞時間
	}ENEMY_PARAM;
	//CSVファイルから読み取った敵データを格納するための構造体
	typedef struct
	{
		int Count;
		int Pattern;
		int Kind;
		float PosX;
		float PosZ;
		float Speed;
		int BulletTime;
		int BulletKind;
		int Color;
		int Hp;
		int BulletKind2;
		int Wait;
		int Item_n[6];
	}ENEMY_ORDER;
	enum ENEMY_KIND{ENEMY0, ENEMY1, ENEMY2};
private:
	ENEMY_PARAM tEnemyParam[ENEMY_MAX];
	ENEMY_ORDER tEnemyOrder[ENEMY_ORDER_MAX];
	void EnemyPattern0(int EnemyCount);
	void EnemyPattern1(int EnemyCount);
	void EnemyPattern2(int EnemyCount);
	void EnemyPattern3(int EnemyCount);
	void EnemyPattern4(int EnemyCount);
	void EnemyPattern5(int EnemyCount);
	void EnemyPattern6(int EnemyCount);
	void EnemyPattern7(int EnemyCount);
	void EnemyPattern8(int EnemyCount);
	void EnemyPattern9(int EnemyCount);
	void EnemyPattern10(int EnemyCount);
	int EnemyNumberSearch();
public:
	CEnemy();
	~CEnemy();
	int LoadEnemy(int EnemyNum, string FileName);
	void UnLoadEnemy(int EnemyNum);
	void LoadEnemyOrder();
	void EnemyEntery(int StageCount);
	void EnemyAction();
	void EnemyDrow(int EnemyNum);
	float Rang(float Angle);
	void (CEnemy::*EnemyPattern[ENEMY_PATTERN_MAX])(int);
};
#endif
Enemy.cpp

コード:

#include "Enemy.h"

CEnemy::CEnemy()
{
	memset(tEnemyParam, 0, sizeof(ENEMY_PARAM) * ENEMY_MAX);//敵データの初期化
	for(int ii = 0; ii < ENEMY_MAX; ii++)
	{
		tEnemyParam[ii].Pos.y = -280.0f;
	}
	memset(tEnemyOrder, 0, sizeof(ENEMY_ORDER) * ENEMY_ORDER_MAX);
}
//------------------------------------------------------------
CEnemy::~CEnemy()
{}
//------------------------------------------------------------
void (CEnemy::*CEnemy::EnemyPattern[ENEMY_PATTERN_MAX])(int) =
	{
		&CEnemy::EnemyPattern0, &CEnemy::EnemyPattern1, &CEnemy::EnemyPattern2,
		&CEnemy::EnemyPattern3, &CEnemy::EnemyPattern4, &CEnemy::EnemyPattern5,
		&CEnemy::EnemyPattern6, &CEnemy::EnemyPattern7, &CEnemy::EnemyPattern8,
		&CEnemy::EnemyPattern9, &CEnemy::EnemyPattern10,
	};
//------------------------------------------------------------
int CEnemy::LoadEnemy(int EnemyNum, std::string FileName)
{
	
	for(int ii = 0; ii < ENEMY_MAX; ii++)
	{
		//SetUseASyncLoadFlag(TRUE);
		switch (EnemyNum)
		{
			case ENEMY0:

				tEnemyParam[ii].ModelHandle[ENEMY0] = MV1LoadModel(FileName.c_str());
				break;

			case ENEMY1:
				tEnemyParam[ii].ModelHandle[ENEMY1] = MV1LoadModel(FileName.c_str());
				break;

			case ENEMY2:
				tEnemyParam[ii].ModelHandle[ENEMY2] = MV1LoadModel(FileName.c_str());
				break;
		}
		//SetUseASyncLoadFlag(FALSE);
		if(tEnemyParam[ii].ModelHandle[EnemyNum] == -1)
		{
			return -1;
		}
		//MV1SetScale(tPlayerParam.PlayerModel[ModelNum], VGet(1, 1, 1));
		//読み込み成功
	}
		return 1;
}
//------------------------------------------------------------
void CEnemy::UnLoadEnemy(int EnemyNum)
{
	for(int ii = 0; ii < ENEMY_MAX; ii++)
	{
		if(tEnemyParam[ii].ModelHandle[EnemyNum] != 0)
		{
			MV1DeleteModel(tEnemyParam[ii].ModelHandle[EnemyNum]);
		}
	}
}
//------------------------------------------------------------
void CEnemy::LoadEnemyOrder()
{
	int Line;
	int Number;
	int fp;
	char FileName[32] = {"EnemyState/storyH0.csv"};
	int input[64];
	char inputc[64];

	fp = FileRead_open(FileName); //ファイルの読み込み
	if(fp == NULL)
	{
		printfDx("read error\n");
		return;
	}
	for(int ii = 0; ii < 2; ii++) //最初の2行は飛ばす
	{
		while(FileRead_getc(fp) != '\n');
	}
	Line = 0;
	Number = 0;
	while(1)
	{
		for(int ii = 0; ii < 64; ii++)
		{
			inputc[ii] = input[ii] = FileRead_getc(fp); //1文字取得する
			if(inputc[ii] == '/') //スラッシュがあれば
			{
				while(FileRead_getc(fp) != '\n'); //開業までループ
				ii = 1; //カウンタを最初に戻す
				continue;
			}
			if(input[ii] == ',' || input[ii] == '\n') //カンマか改行なら
			{
				inputc[ii] = '\0'; //そこまでを文字列とする
				break;
			}
			if(input[ii] == EOF) //ファイルの終わりなら
			{
				goto EXFILE; //終了
			}
		}
		switch(Number)
		{
			case 0:
				tEnemyOrder[Line].Count = atoi(inputc);
				break;
			case 1:
				tEnemyOrder[Line].Pattern = atoi(inputc);
				break;
			case 2:
				tEnemyOrder[Line].Kind = atoi(inputc);
				break;
			case 3:
				tEnemyOrder[Line].PosX = atoi(inputc);
				break;
			case 4:
				tEnemyOrder[Line].PosZ = atoi(inputc);
				break;
			case 5:
				tEnemyOrder[Line].Speed = atoi(inputc);
				break;
			case 6:
				tEnemyOrder[Line].BulletTime = atoi(inputc);
				break;
			case 7:
				tEnemyOrder[Line].BulletKind = atoi(inputc);
				break;
			case 8:
				tEnemyOrder[Line].Color = atoi(inputc);
				break;
			case 9:
				tEnemyOrder[Line].Hp = atoi(inputc);
				break;
			case 10:
				tEnemyOrder[Line].BulletKind2 = atoi(inputc);
				break;
			case 11:
				tEnemyOrder[Line].Wait = atoi(inputc);
				break;
			case 12:
				tEnemyOrder[Line].Item_n[0] = atoi(inputc);
				break;
			case 13:
				tEnemyOrder[Line].Item_n[1] = atoi(inputc);
				break;
			case 14:
				tEnemyOrder[Line].Item_n[2] = atoi(inputc);
				break;
			case 15:
				tEnemyOrder[Line].Item_n[3] = atoi(inputc);
				break;
			case 16:
				tEnemyOrder[Line].Item_n[4] = atoi(inputc);
				break;
			case 17:
				tEnemyOrder[Line].Item_n[5] = atoi(inputc);
				break;
		}
		Number++;
		if(Number == 18)
		{
			Number = 0;
			Line++;
		}
	}
EXFILE:
	FileRead_close(fp);
}
//------------------------------------------------------------
void CEnemy::EnemyPattern0(int EnemyCount)
{
	if(tEnemyParam[EnemyCount].Count == 0)
	{
		tEnemyParam[EnemyCount].VZ = -0.5f; //下がってくる
	}
	if(tEnemyParam[EnemyCount].Count == 40)
	{
		tEnemyParam[EnemyCount].VZ = 0.0f; //止まる
	}
	if(tEnemyParam[EnemyCount].Count == 40 + tEnemyParam[EnemyCount].Wait) //登録された時間だけ停滞する
	{
		tEnemyParam[EnemyCount].VZ = 0.5f; //上がっていく
	}
}
//------------------------------------------------------------
void CEnemy::EnemyPattern1(int EnemyCount)
{
	if(tEnemyParam[EnemyCount].Count == 0)
	{
		tEnemyParam[EnemyCount].VZ = -0.5f; //下がってくる
	}
	if(tEnemyParam[EnemyCount].Count == 40)
	{
		tEnemyParam[EnemyCount].VZ = 0; //止まる
	}
	if(tEnemyParam[EnemyCount].Count == 40 + tEnemyParam[EnemyCount].Wait) //登録された時間だけ停滞する
	{
		tEnemyParam[EnemyCount].VX = -0.3f; //左へ
		tEnemyParam[EnemyCount].VZ = -0.4f; //下がっていく
		tEnemyParam[EnemyCount].Muki = 0; //左向きセット
	}
}
//------------------------------------------------------------
void CEnemy::EnemyPattern2(int EnemyCount)
{
	if(tEnemyParam[EnemyCount].Count == 0)
	{
		tEnemyParam[EnemyCount].VZ = -0.5f; //下がる
	}
	if(tEnemyParam[EnemyCount].Count == 40)
	{
		tEnemyParam[EnemyCount].VZ = 0.0f; //停滞する
	}
	if(tEnemyParam[EnemyCount].Count == 40 + tEnemyParam[EnemyCount].Wait)
	{
		tEnemyParam[EnemyCount].VX = 0.3f; //右へ
		tEnemyParam[EnemyCount].VZ = -0.4f; //下がる
		tEnemyParam[EnemyCount].Muki = 2; //右向きセット
	}
}
//------------------------------------------------------------
void CEnemy::EnemyPattern3(int EnemyCount)
{
	if(tEnemyParam[EnemyCount].Count == 0)
	{
		tEnemyParam[EnemyCount].VZ = -0.7f;
	}
	if(tEnemyParam[EnemyCount].Count == 30)
	{
		tEnemyParam[EnemyCount].Muki = 0;
	}
	if(tEnemyParam[EnemyCount].Count < 100)
	{
		tEnemyParam[EnemyCount].VX -= 0.7f / 100.0f;
		tEnemyParam[EnemyCount].VZ += 0.4f / 100.0f;
	}
}
//------------------------------------------------------------
void CEnemy::EnemyPattern4(int EnemyCount)
{
	if(tEnemyParam[EnemyCount].Count == 0)
	{
		tEnemyParam[EnemyCount].VZ = -0.7f;
	}
	if(tEnemyParam[EnemyCount].Count == 30)
	{
		tEnemyParam[EnemyCount].Muki = 2;
	}
	if(tEnemyParam[EnemyCount].Count < 100)
	{
		tEnemyParam[EnemyCount].VX += 0.7f / 100.0f;
		tEnemyParam[EnemyCount].VZ -= 0.7f / 100.0f;
	}
}
//------------------------------------------------------------
void CEnemy::EnemyPattern5(int EnemyCount)
{
	if(tEnemyParam[EnemyCount].Count == 0)
	{
		tEnemyParam[EnemyCount].VX -= 0.3f;
		tEnemyParam[EnemyCount].VZ = -0.4f;
		tEnemyParam[EnemyCount].Muki = 0;
	}
}
//------------------------------------------------------------
void CEnemy::EnemyPattern6(int EnemyCount)
{
	if(tEnemyParam[EnemyCount].Count == 0)
	{
		tEnemyParam[EnemyCount].VX += 0.3f;
		tEnemyParam[EnemyCount].VZ = -0.4f;
		tEnemyParam[EnemyCount].Muki = 2;
	}
}
//------------------------------------------------------------
void CEnemy::EnemyPattern7(int EnemyCount)
{
	if(tEnemyParam[EnemyCount].Count == tEnemyParam[EnemyCount].Wait)
	{
		tEnemyParam[EnemyCount].VX =-0.1f;
		tEnemyParam[EnemyCount].VZ =+0.08f;
		tEnemyParam[EnemyCount].Muki = 0;
	}
}
//------------------------------------------------------------
void CEnemy::EnemyPattern8(int EnemyCount)
{
	if(tEnemyParam[EnemyCount].Count == tEnemyParam[EnemyCount].Wait)
	{
		tEnemyParam[EnemyCount].VX =+0.1f;
		tEnemyParam[EnemyCount].VZ =+0.08f;
		tEnemyParam[EnemyCount].Muki = 2;
	}
}
//------------------------------------------------------------
void CEnemy::EnemyPattern9(int EnemyCount)
{
	if(tEnemyParam[EnemyCount].Count == tEnemyParam[EnemyCount].Wait)
	{
		tEnemyParam[EnemyCount].VZ = 0.3f;
	}
}
//------------------------------------------------------------
void CEnemy::EnemyPattern10(int EnemyCount)
{
	if(tEnemyParam[EnemyCount].Count == 0)
	{
		tEnemyParam[EnemyCount].VZ = -0.6f;
	}
	if(tEnemyParam[EnemyCount].Count == 40)
	{
		tEnemyParam[EnemyCount].VZ = 0.0f;
	}
	if(tEnemyParam[EnemyCount].Count > 40)
	{
		if(tEnemyParam[EnemyCount].Count % 60 == 0)
		{
			int rng = cos(tEnemyParam[EnemyCount].Angle) < 0 ? 0 : 1;
			tEnemyParam[EnemyCount].Spd = 0.7 + Rang(2);
			tEnemyParam[EnemyCount].Angle = Rang(PI/4) + PI * rng;
			tEnemyParam[EnemyCount].Muki = 2 - 2 * rng;
		}
		tEnemyParam[EnemyCount].Spd *= 0.55f;
	}
	if(tEnemyParam[EnemyCount].Count >= 40 + tEnemyParam[EnemyCount].Wait)
	{
		tEnemyParam[EnemyCount].VZ += 0.008f;
	}
}
//------------------------------------------------------------
int CEnemy::EnemyNumberSearch()
{
	for(int ii = 0; ii < ENEMY_MAX; ii++)//フラグの立っていないEnemyを探す
	{
		if(tEnemyParam[ii].Flag == 0)
		{
			return ii; //使用可能番号を返す
		}
	}
	return -1; //全部埋まっていたらエラーを返す
}
//------------------------------------------------------------
void CEnemy::EnemyEntery(int StageCount)
{
	int Number = 0;
	for(int ii = 0; ii < ENEMY_ORDER_MAX; ii++)
	{
		//現在の瞬間がオーダーの瞬間なら
		if(tEnemyOrder[ii].Count == StageCount)
		{
			if((Number = EnemyNumberSearch()) != -1)
			{
				tEnemyParam[Number].Flag = 1;
				tEnemyParam[Number].Count = 0;
				tEnemyParam[Number].Pattern = tEnemyOrder[ii].Pattern;
				tEnemyParam[Number].Muki = 1;
				tEnemyParam[Number].Kind = tEnemyOrder[ii].Kind;
				tEnemyParam[Number].Pos.x = tEnemyOrder[ii].PosX;
				tEnemyParam[Number].Pos.z = tEnemyOrder[ii].PosZ;
				tEnemyParam[Number].Spd = tEnemyOrder[ii].Speed;
				tEnemyParam[Number].BulletTime = tEnemyOrder[ii].BulletTime;
				tEnemyParam[Number].BulletKind = tEnemyOrder[ii].BulletKind;
				tEnemyParam[Number].BulletKind2 = tEnemyOrder[ii].BulletKind2;
				tEnemyParam[Number].Color = tEnemyOrder[ii].Color;
				tEnemyParam[Number].Wait = tEnemyOrder[ii].Wait;
				tEnemyParam[Number].Hp = tEnemyOrder[ii].Hp;
				tEnemyParam[Number].MaxHp = tEnemyOrder[ii].Hp;
				tEnemyParam[Number].VX = 0;
				tEnemyParam[Number].VZ = 0;
				tEnemyParam[Number].Angle = 0;
				for(int jj = 0; jj < 6; jj++)
				{
					tEnemyParam[Number].Item_n[jj] = tEnemyOrder[ii].Item_n[jj];
				}
				MV1SetPosition(tEnemyParam[Number].ModelHandle[ENEMY0], tEnemyParam[Number].Pos);
			}
		}
	}
}
//------------------------------------------------------------
void CEnemy::EnemyAction()
{
	for(int ii = 0; ii < ENEMY_MAX; ii++)
	{
		//敵のフラグがオンだったら
		if(tEnemyParam[ii].Flag == 1)
		{
			EnemyPattern[tEnemyParam[ii].Pattern](ii);
			tEnemyParam[ii].Pos.x += cos(tEnemyParam[ii].Angle) * tEnemyParam[ii].Spd;
			tEnemyParam[ii].Pos.z += sin(tEnemyParam[ii].Angle) * tEnemyParam[ii].Spd;
			tEnemyParam[ii].Pos.x += tEnemyParam[ii].VX;
			tEnemyParam[ii].Pos.z += tEnemyParam[ii].VZ;
			tEnemyParam[ii].Count++;
			tEnemyParam[ii].Model = tEnemyParam[ii].Muki * 3 + (tEnemyParam[ii].Count % 18) / 6;
			//敵が画面外から外れたら消す
			if(tEnemyParam[ii].Pos.x < 248 || tEnemyParam[ii].Pos.x > 390 || tEnemyParam[ii].Pos.z < 170 || tEnemyParam[ii].Pos.z > 325)
			{
				tEnemyParam[ii].Flag = 0;
			}
			MV1SetPosition(tEnemyParam[ii].ModelHandle[ENEMY0], tEnemyParam[ii].Pos);
		}
	}
}
//------------------------------------------------------------
void CEnemy::EnemyDrow(int EnemyNum)
{
	VECTOR POS;
	for(int ii = 0; ii < ENEMY_MAX; ii++)
	{
		if(tEnemyParam[ii].Flag == 1)
		{
			MV1DrawModel(tEnemyParam[ii].ModelHandle[tEnemyParam[ii].Kind]);
		}
		POS = MV1GetPosition(tEnemyParam[ii].ModelHandle[EnemyNum]);
	}
}
//------------------------------------------------------------
float CEnemy::Rang(float Angle)
{
	return (-Angle + Angle * 2 * GetRand(10000) / 10000.0f);
}
現在はコンパイル時に下記のエラーが出ております。
error C2761: 'void (__thiscall CEnemy::* CEnemy::EnemyPattern[11])(int)' : メンバ関数の再宣言はできません。
fatal error C1903: 直前のエラーを修復できません。コンパイルを中止します。

どうか関数ポインタについて詳しくご教授いただけたらと思います。

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

Re: クラス内での関数ポインタの使用について

#2

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

north さんが書きました:現在はコンパイル時に下記のエラーが出ております。
error C2761: 'void (__thiscall CEnemy::* CEnemy::EnemyPattern[11])(int)' : メンバ関数の再宣言はできません。
fatal error C1903: 直前のエラーを修復できません。コンパイルを中止します。
Enemy.cppの16行目を

コード:

void (CEnemy::*EnemyPattern[ENEMY_PATTERN_MAX])(int) =
とするとコンパイルが通るかもしれません。
実験に用いたコード:

コード:

#include <stdio.h>

struct a {
    void aaa(int b){printf("%d\n",b);}
    void aaaa(int b){printf("%d\n",b*2);}
    void aaaaa(int b){printf("%d\n",b*3);}
    void (a::*ap[3])(int);
};

#if 1
void (a::*ap[3])(int) = { // 通る
#else
void (a::*a::ap[3])(int) = { // 通らない
#endif
    &a::aaa, &a::aaaa, &a::aaaaa
};

int main(void) {
    return 0;
}
north さんが書きました:どうか関数ポインタについて詳しくご教授いただけたらと思います。
[search=google]関数ポインタ[/search]
[search=google]C++ メンバ関数 ポインタ[/search]
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

north

Re: クラス内での関数ポインタの使用について

#3

投稿記事 by north » 10年前

ご回答ありがとうございます。
2点ご質問があるのですが、
・ご指摘いただいた通りに修正いたしましたらメンバ関数がprivateだからアクセスできないとエラーが出てきたのですが
同じクラスのメンバ関数なのになぜこのようなエラーが出てくるのかわからないです。

・指摘されたメンバ関数をpublicに移しましたら395行目を(this->*EnemyPattern[tEnemyParam[ii].Pattern])(ii);
と修正したのですがハンドルされていない例外が発生しましたとこの行で止まってしまいます。
これはメンバ関数の呼び出し方を間違っているからなのでしょうか?
もし、そうだとしたらどのように呼び出せばよろしいでしょうか?(thisポインタの中はエラーです。式を評価できませんとなっていました。)

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

Re: クラス内での関数ポインタの使用について

#4

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

north さんが書きました:・ご指摘いただいた通りに修正いたしましたらメンバ関数がprivateだからアクセスできないとエラーが出てきたのですが
同じクラスのメンバ関数なのになぜこのようなエラーが出てくるのかわからないです。
16行目はクラスの外にあるので、クラスのprivateなメンバ関数にはアクセスできません。
north さんが書きました:・指摘されたメンバ関数をpublicに移しましたら395行目を(this->*EnemyPattern[tEnemyParam[ii].Pattern])(ii);
と修正したのですがハンドルされていない例外が発生しましたとこの行で止まってしまいます。
これはメンバ関数の呼び出し方を間違っているからなのでしょうか?
もし、そうだとしたらどのように呼び出せばよろしいでしょうか?(thisポインタの中はエラーです。式を評価できませんとなっていました。)
メンバ変数EnemyPattern[tEnemyParam[ii].Pattern]は初期化されていないため、
謎の場所を呼び出してアクセス違反になっていると思います。
コンストラクタで初期化するといいかもしれません。

コード:

#include <stdio.h>
 
struct a {
    private:
    void aaa(int b){printf("%d\n",b);}
    void aaaa(int b){printf("%d\n",b*2);}
    void aaaaa(int b){printf("%d\n",b*3);}
    public:
    void (a::*ap[3])(int);
    void b(int bb);
    a();
};

#if 0 // 1にするとコンパイルエラー
void (a::*ap[3])(int) = {
    &a::aaa, &a::aaaa, &a::aaaaa
};
#endif

a::a() {
#if 1 // 0にするとSegmentation Fault
    ap[0] = &a::aaaaa;
    ap[1] = &a::aaaa;
    ap[2] = &a::aaa;
#endif
}

void a::b(int bb) {
    (this->*ap[0])(bb);
}

int main(void) {
    a va;
    va.b(123);
    return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

north

Re: クラス内での関数ポインタの使用について

#5

投稿記事 by north » 10年前

ありがとうございます。
頂いたアドバイスを基に修正いたしましたら無事にこちらの想定していた動作をするようになりました。
1つずつ配列を初期化していくともっと増えた場合大変なのでここは時間があれば工夫したいところです・・・・・・
みけCAT さんが書きました: 16行目はクラスの外にあるので、クラスのprivateなメンバ関数にはアクセスできません。
関数のメンバポインタは一度しっかりと勉強して理解を深めた方がいいと痛感しております。
これを機に今一度本などを読み少しずつ使用していって理解を深めたいと思います。

閉鎖

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