ページ 11

クラス内の関数ポインタ

Posted: 2014年2月20日(木) 19:25
by bono

コード:

class Game
{
	~
	//ゲームのタイトル画面
	int GameTitle();
	//メイン関数
	int GameMain();

	//関数ポインタ
	int (Game::*Scene)(){};
};
コンストラクタで
Scene = &Game::Title;

ヘッダーで
Game *game;
メイン関数で
(game->*Scene)();
とすると
error C2065: 'Scene' : 定義されていない識別子です。
とでてコンパイルが通りません。

Re: クラス内の関数ポインタ

Posted: 2014年2月20日(木) 19:27
by みけCAT
(game->*Scene)();は、(game->Scene)();または(*(game->Scene))();の間違いではないですか?

Re: クラス内の関数ポインタ

Posted: 2014年2月20日(木) 19:34
by bono
みけCAT さんが書きました:(game->*Scene)();は、(game->Scene)();または(*(game->Scene))();の間違いではないですか?
(game->Scene)();
error C2064: 0 引数を取り込む関数には評価されません。

(*(game->Scene))();
error C2171: '*' : 'int (__thiscall Game::* )(void)' のオペランドが無効です。
error C2064: 0 引数を取り込む関数には評価されません。
どちらとも無理です。

Re: クラス内の関数ポインタ

Posted: 2014年2月20日(木) 19:52
by みけCAT
関数ポインタの宣言が怪しいと思います。
Game::Titleの型は何ですか?
関数ポインタの宣言の書き方は、例えばqsortの第四引数が参考になると思います。
苦C さんが書きました:void qsort(void *base, size_t nel, size_t width,
    int(*compar)(const void *x, const void *y));
(http://9cguide.appspot.com/r_lib.html)

Re: クラス内の関数ポインタ

Posted: 2014年2月20日(木) 19:58
by hoge
(game->game->*Scene)();で
>int (Game::*Scene)(){};これはコンパイル通るの?{}が余分なような

Re: クラス内の関数ポインタ

Posted: 2014年2月20日(木) 20:00
by hoge
違った
(game->*game->Scene)();だ。

Re: クラス内の関数ポインタ

Posted: 2014年2月20日(木) 20:01
by bono
hoge さんが書きました:(game->game->*Scene)();で
>int (Game::*Scene)(){};これはコンパイル通るの?{}が余分なような
{}は通らなくて追加したもので、無いと思ってください。
結果は変わりません。

Re: クラス内の関数ポインタ

Posted: 2014年2月20日(木) 20:14
by みけCAT
この位置で関数ポインタの変数を宣言するのに、Game::はつけなくていいのではないでしょうか?

Re: クラス内の関数ポインタ

Posted: 2014年2月20日(木) 20:32
by bono
みけCAT さんが書きました:この位置で関数ポインタの変数を宣言するのに、Game::はつけなくていいのではないでしょうか?
何ですか?

Re: クラス内の関数ポインタ

Posted: 2014年2月20日(木) 20:40
by みけCAT
bono さんが書きました:
みけCAT さんが書きました:この位置で関数ポインタの変数を宣言するのに、Game::はつけなくていいのではないでしょうか?
何ですか?
何ですかって何ですか?

日本語わかりますか?
無理をせず、英語で質問してもいいですよ。(投稿には日本語の文字を含めることが必要です)

Re: クラス内の関数ポインタ

Posted: 2014年2月20日(木) 20:51
by softya(ソフト屋)
とりあえず落ち着いて下さい。
bono さんは、コンパクトにエラーを再現できるコードを投稿してもらうと話が早く進むと思います。
「何ですか?」は「何でですか?」の間違いとだと思いますが、もう少し丁寧な言葉でお願いします。

みけCATさんも、言葉選びは慎重にお願いします。

Re: クラス内の関数ポインタ

Posted: 2014年2月20日(木) 23:37
by yukihiro
bono さんが書きました: Scene = &Game::Title;

Scene = &Game::GameTitle;
の誤りでしょう。

回答(というか質問が見当たらないですが)としては
hogeさんが既に出してますね。

Re: クラス内の関数ポインタ

Posted: 2014年2月21日(金) 00:50
by へにっくす
とりあえず以下でコンパイルできたが、なんだか気持ち悪いな (^^;

コード:

#include <iostream>
using namespace std;

class Game
{
	public:
	Game();
	//ゲームのタイトル画面
	int GameTitle();
	//メイン関数
	int GameMain();

	//関数ポインタ
	int (Game::*Scene)();
};

Game::Game()
{
	Scene = &Game::GameTitle;
}

int Game::GameTitle()
{
	cout << "GameTitle";
	return 0;
}


void main(void)
{
	Game game;
	(game.*game.Scene)();
}

コード:

C:\Users\****>cl /EHsc 1.cpp
Microsoft(R) C/C++ Optimizing Compiler Version 17.00.61030 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

1.cpp
Microsoft (R) Incremental Linker Version 11.00.61030.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:1.exe
1.obj

C:\Users\****>1
GameTitle
C:\Users\****>
Gameをnewしてる場合は、hogeさんのでokなはず。

Re: クラス内の関数ポインタ

Posted: 2014年2月21日(金) 09:20
by usao
文法がどうなってんだ? という混乱時には,
丁寧に括弧を付けるとわかりやすいのではないでしょうか.

コード:

#include <iostream>

class Game
{
public:
    Game::Game(){   Scene=&Game::GameTitle; }
    int GameTitle(){    std::cout << "title" << std::endl;  return 1;   }
    int ( Game::*Scene )();  //メンバ関数ポインタ
};

int main( int argc, char **argv )
{
    Game *game = new Game;

    //(1) game->Scene がメンバ関数ポインタ.
    //(2) それをコールするための演算子->* を使うと
    //    ( Game型インスタンスへのポインタ->*( game->Scene ) )();
    //(3) 呼び出すGameインスタンス(へのポインタ)がここではgameなので
    //    ( game->*( game->Scene ) )();
    ( game->*( game->Scene ) )();

    delete game;
    std::cin.ignore();
    return 0;
}
オフトピック
トピックのタイトルのせいか,
やりたいことが 単なる(?)関数ポインタ ではなく,クラスのメンバ関数へのポインタ の話だという点が
みけCATさんにうまく伝わらなかったんじゃないかな.
まぁコードを見れば推測できる範囲だと言えなくもないけど,
やっぱ内容に沿ったタイトルと,きちんとした質問内容を書かないとこういう食い違いが起こるってことですよね.

Re: クラス内の関数ポインタ

Posted: 2014年2月21日(金) 09:30
by みけCAT
usao さんが書きました:
オフトピック
トピックのタイトルのせいか,
やりたいことが 単なる(?)関数ポインタ ではなく,クラスのメンバ関数へのポインタ の話だという点が
みけCATさんにうまく伝わらなかったんじゃないかな.
まぁコードを見れば推測できる範囲だと言えなくもないけど,
やっぱ内容に沿ったタイトルと,きちんとした質問内容を書かないとこういう食い違いが起こるってことですよね.
C++をよくわかっていないのに、適当な推論で回答してしまい申し訳ありませんでした。
今度から、このような時はきちんとコンパイルが通ることを確認してから回答するように気をつけたいと思います。

Re: クラス内の関数ポインタ

Posted: 2014年2月21日(金) 12:25
by かずま
へにっくす さんが書きました:とりあえず以下でコンパイルできたが、なんだか気持ち悪いな (^^;

コード:

#include <iostream>

class A {
public:
    A(int (A::*pf)(), int v); // コンストラクタ

    int f1();  // メンバ関数
    int f2();  // メンバ関数

    int (A::*pf_)();  // メンバ変数
    int v_;           // メンバ変数
};

A::A(int (A::*pf)(), int v) : pf_(pf), v_(v) { }
int A::f1() { std::cout << "f1(): v = " << v_ << std::endl; }
int A::f2() { std::cout << "f2(): v = " << v_ << std::endl; }
    
int main()
{
    A *p1 = new A(&A::f1, 11);
    A *p2 = new A(&A::f2, 22);
    (p1->*p2->pf_)();
    delete p2;
    delete p1;
}
実行結果

コード:

f2(): v = 11
(p1->*p2->pf_)(); は、(p1->*(p2->pf_))(); と同じで、
p2 は、どのオブジェクトのメンバ変数pf_ かを示し、
p1 は、どのオブジェクトに対してメンバ関数を呼び出すのかを示します。
呼び出されたメンバ関数側では p1 が this になります。