staticでは無いメンバ関数ポインタを、関数へ – プログラミング – Home

staticでは無いメンバ関数ポインタ...
 
通知
すべてクリア

[解決済] staticでは無いメンバ関数ポインタを、関数へ

固定ページ 1 / 2

tiha
 tiha
(@tiha)
ゲスト
結合: 21年前
投稿: 8
Topic starter  

例えば、関数ポインタを引数に取る関数functionがあるとして、

typedef void (*Callback)( int n );

void Function( Callback cb )
{
cb( 100 );
}

というような。

このFunctionのcbへ、staticではないメンバ関数ポインタ、
例えば以下のHogeのFncメソッド

struct Hoge
{
void Fnc( int n ){ cout << n << end; }
};

を渡すにはどうしたらよいのでしょうか?
typedefや、Functionが変更不可ということで。

Hoge hoge;
Function( ????? );

------
(vc6)


引用未解決
トピックタグ
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

#include <iostream>

struct Hoge
{
void Callback( int n )
{
std::cout << n << std::endl;
}
};

typedef void ( Hoge::*CALLBACK )( int );

void Test( CALLBACK func, Hoge *pHoge, int n )
{
( pHoge->*func )( n );
}

int main()
{
Hoge hoge;
Test( &Hoge::Callback, &hoge, 10 );
return 0;
}

こんな感じで。
Hoge のインスタンスを渡してやらないと呼べません。
int main()
{
Test( &CTest::Callback, &test, 10 );
return 0;
}


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

なんか下にごみが残ったね。
2つ目の main は無視してください。


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

関数名変だけど気にしないでね…


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

もうここまで来たら一人で書きまくってるの気にしないでどんどんいこー。

> typedefや、Functionが変更不可ということで。
void Fnc( int n ) と void Hoge::Fnc( int n ) は全然別物なので、typedef を変えな
いのは無理です。
Hoge のインスタンスが必要なので、Function を変えないのも無理です。

以下、関数名等を tiha さんのに極力合わせたサンプル。

#include <iostream>

struct Hoge
{
void Fnc( int n )
{
std::cout << n << std::endl;
}
};

typedef void ( Hoge::*CALLBACK )( int );

void Function( CALLBACK cb, Hoge &hoge, int n )
{
( hoge.*cb )( n );
}

int main()
{
Hoge hoge;
Function( &Hoge::Fnc, hoge, 100 );
return 0;
}


返信引用
鷲尾不徳
 鷲尾不徳
(@鷲尾不徳)
ゲスト
結合: 21年前
投稿: 21
 

> typedefや、Functionが変更不可ということで。
Hoge::Fncは変えるな、と言及されてなかったので…
こんなのでどお?

#include <iostream>

typedef void ( *Callback )( int n );

void Function( Callback cb )
{
cb( 100 );
}

void Fnc( int n )
{
std::cout << n << std::endl;
}

struct Hoge
{
Hoge():Fnc(::Fnc){}; //コンストラクタで関数ポインタ渡し
Callback Fnc;
};

int main( int,char** )
{
Hoge hoge;
Function( hoge.Fnc );
return 0;
}

struct からの関数ポインタ渡しだったので咄嗟にこっちがでてきた。
BCCでは通りましたが・・・反則ですか?


返信引用
tiha
 tiha
(@tiha)
ゲスト
結合: 21年前
投稿: 8
Topic starter  

>void Fnc( int n ) と void Hoge::Fnc( int n ) は全然別物なので、
>typedef を変えないのは無理です。
>Hoge のインスタンスが必要なので、Function を変えないのも無理です。

無理ですか・・。それがわかっただけでもよかったです。
ありがとうございました。

static変数使う方法を一つみつけました。
#include <iostream>

struct Hoge
{
  static void* m_p;
void Fnc( int n )
{
std::cout << n << std::endl;
}
static Callback( n );
{
Hoge* phoge = (Hoge*)m_p;
phoge->Fnc( n );
}
};
void* Hoge::m_p;

typedef void ( *CALLBACK )( int );

void Function( CALLBACK cb )
{
cb( 100 );
}

int main()
{
Hoge hoge;
Hoge::m_p = &hoge;
Function( &Hoge::Fnc );
return 0;
}

て、ちと無理あるか・・


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

エラー出ますよ(VC++.NET 2003)。
やっぱり、
void Func( int )
を取る関数に
void Hoge::Func( int )
は渡せません。


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

↑のは、tiha さん@21:03:38 へのレスです。
で、鷲尾不徳 さん

それって、

#include <iostream>

typedef void ( *Callback )( int n );

void Function( Callback cb )
{
cb( 100 );
}

void Fnc( int n )
{
std::cout << n << std::endl;
}

int main( int,char** )
{
Function( Fnc );
return 0;
}

と同じじゃん。
呼び出す対象の Fnc が Hoge のメンバじゃないですもん。


返信引用
tiha
 tiha
(@tiha)
ゲスト
結合: 21年前
投稿: 8
Topic starter  

あ、すいません。

> Function( &Hoge::Fnc );

は、
Function( &Hoge::Callback );

の間違いでした。


返信引用
鷲尾不徳
 鷲尾不徳
(@鷲尾不徳)
ゲスト
結合: 21年前
投稿: 21
 

>と同じじゃん。
>呼び出す対象の Fnc が Hoge のメンバじゃないですもん。

自分のじゃ、見た目それっぽく動くようにごまかしただけですね…


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

そこまで言うならお目にかけよう、禁断の魔技!
…まともに動きゃしねぇがな。
よい子は真似しちゃいけないよっ☆

#include <iostream>
#include <cstdio>

struct Hoge
{
void Fnc( int n )
{
std::cout << n << std::endl;
}
};

typedef void ( *CALLBACK )( int );

void Function( CALLBACK cb, int n )
{
( *cb )( n );
}

int main()
{
char s[ 80 ];
std::memset( s, 0, 80 );
std::sprintf( s, %p, ( &Hoge::Fnc ) );

long lPtr = std::strtol( s, NULL, 16 );
CALLBACK pFunc = reinterpret_cast< CALLBACK >( lPtr );

Function( pFunc, 100 );
return 0;
}


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

>tiha さん
Hoge に static な Callback を追加するのと、
Fnc 自体を static にするのはさほど変わらないような…

「Function と typedef を変更しない」にこだわるあまり
「コールバック関数のアドレスとして static でないものを渡す」が軽視されてます。


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

禁断の魔技の sprintf / strtol がやってることを自力でやってみる。
使い物にならないことに変わりはない。

#include <iostream>
#include <cstdarg>

struct Hoge
{
void Fnc( int n )
{
std::cout << n << std::endl;
}
};

typedef void ( *CALLBACK )( int );

void Function( CALLBACK cb )
{
( *cb )( 100 );
}

void Test( int dummy, ... )
{
va_list ap;
va_start( ap, dummy );

CALLBACK pFunc = va_arg( ap, CALLBACK );
Function( pFunc );

va_end( ap );
}

int main()
{
Test( 0, &Hoge::Fnc );
return 0;
}


返信引用
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
 

真っ当な方法ではどうやっても無理だと思います。
俺の禁断の魔技みたいな、真っ当じゃない方法でも可能性を模索しますか?
そうなるともはや、インラインアセンブラとか使わざるを得ない気がしますが。
俺はそっちはわかんないので、どなたか「やってみよう」と思う方がいらっしゃいまし
たらお願いします。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました