高分求实现方法
不论用什么方法将一个指向类成员函数的指针,赋给一般函数指针,并且调用成功。
例子:
class A
{
public:
int t;
void print(){cout<<i<<endl;};
};
//
.....
如何用一个指向一般函数的指针来调用print.
问题点数:280、回复次数:28Top
1 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 17:41:12 得分 0
补充一句,可以用任何方法Top
2 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 17:48:02 得分 0
upTop
3 楼Jneu(沧海桑田)回复于 2001-09-24 17:48:18 得分 0
upTop
4 楼Jneu(沧海桑田)回复于 2001-09-24 17:48:27 得分 0
upTop
5 楼Jneu(沧海桑田)回复于 2001-09-24 17:48:36 得分 0
upTop
6 楼cber(cber)回复于 2001-09-24 17:50:12 得分 90
转贴bugn所写的“用template partial specialization模拟borland C++中的closure类型函数指针”
#include <iostream>
#include <utility>
using namespace std;
//
// a simulation for the closure keyword in borland c++ compiler
//
// written by bugn, Feb 8, 2001
//
template <typename T> // traits class
struct MemFuncTraits {};
template <typename R, typename O> // partial specialization
struct MemFuncTraits<R (O::*)()> { // for zero-parameter
typedef R ReturnType; // non-const member
typedef O ObjectType; // functions
};
template <typename R, typename O> // partial specialization
struct MemFuncTraits<R (O::*)() const> { // for zero-parameter
typedef R ReturnType; // const member
typedef O ObjectType; // functions
};
template <typename R, typename O, typename P1> // partial specialization
struct MemFuncTraits<R (O::*)(P1)> { // for one-parameter
typedef R ReturnType; // non-const member
typedef O ObjectType; // functions
};
template <typename R, typename O, typename P1> // partial specialization
struct MemFuncTraits<R (O::*)(P1) const> { // for one-parameter
typedef R ReturnType; // const member
typedef O ObjectType; // functions
};
template <typename R, typename O, typename P1, typename P2> // partial specialization
struct MemFuncTraits<R (O::*)(P1,P2)> { // for two-parameter
typedef R ReturnType; // non-const member
typedef O ObjectType; // functions
};
template <typename R, typename O, typename P1, typename P2> // partial specialization
struct MemFuncTraits<R (O::*)(P1,P2) const> { // for two-parameter
typedef R ReturnType; // const member
typedef O ObjectType; // functions
};
// u can extend MemFuncTraits to support more parameters
//
template <typename MemFuncPtrType>
struct Closure {
public:
typedef typename MemFuncTraits<MemFuncPtrType>::ObjectType ObjectType;
typedef typename MemFuncTraits<MemFuncPtrType>::ReturnType ReturnType;
typedef pair<ObjectType*, MemFuncPtrType> CallInfo;
Closure(ObjectType* pobj, MemFuncPtrType ptr_fun) : call_info(make_pair(pobj, ptr_fun)){
}
Closure& bind(ObjectType* pobj, MemFuncPtrType ptr_fun) {
call_info.first = pobj;
call_info.second = ptr_fun;
}
// NOTE! the following assignment operator must be used with caution !
Closure& operator=(MemFuncPtrType ptr_fun) {
call_info.second = ptr_fun;
}
// NOTE! the following assignment operator must be used with caution !
Closure& operator=(ObjectType* pobj) {
call_info.first = pobj;
}
// support for 0 parameters
ReturnType operator()() const {
return (call_info.first->*call_info.second)();
}
// support for 1 parameter
template <typename Param1Type>
ReturnType operator()(Param1Type p1) const {
return (call_info.first->*call_info.second)(p1);
}
// support for 2 parameter2
template <typename Param1Type, typename Param2Type>
ReturnType operator()(Param1Type p1, Param2Type p2) const {
return (call_info.first->*call_info.second)(p1, p2);
}
// u can extend it to support more parameters
//
private:
CallInfo call_info;
};
//
// the following is a simple test for our closure template
//
struct Wombat {
virtual int dig(short cid)
{
cout << "[" << cid << "] " << "Wombat digging...\n";
return 1;
}
int sleep(short cid)
{
cout << "[" << cid << "] " << "Wombat sleeping...\n";
return 5;
}
};
struct BabyWombat : public Wombat {
int dig(short cid)
{
cout << "[" << cid << "] " << "Baby wombat digging...\n";
return 1;
}
int sleep(short cid)
{
cout << "[" << cid << "] " << "Baby wombat sleeping...\n";
return 5;
}
};
void main()
{
Wombat wb;
BabyWombat baby;
typedef int (Wombat::*PWMF)(short); // pointer to a Wombat member function
Closure<PWMF> fp(&wb, &Wombat::dig);
fp(1);
fp = &Wombat::sleep;
fp(2);
fp = &baby;
fp(3);
fp = &Wombat::dig;
fp(4);
fp = (PWMF)&BabyWombat::sleep;
fp(5);
}
Top
7 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 18:00:42 得分 0
厉害厉害,不是看得很仔细,我想你是用一个类来模拟指针,也就是说并不是真正的将
两个指针互相转化吧,不知道我说的对不对,见笑了Top
8 楼tohigh(岁月的童话.NET)回复于 2001-09-24 18:21:51 得分 0
学习.Top
9 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 18:56:08 得分 0
可以用任何方法,upTop
10 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 19:17:05 得分 0
upTop
11 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 19:52:03 得分 0
upTop
12 楼Only_I(我)回复于 2001-09-24 20:22:14 得分 0
请问i在哪里?Top
13 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 21:37:17 得分 0
你自己可以产生一个实例
A a;然后调用Top
14 楼handsome1234(我太菜了,)回复于 2001-09-24 23:31:45 得分 0
heheTop
15 楼cker(〖烟波浩淼三千里、人鬼殊途五百年〗)回复于 2001-09-24 23:54:00 得分 90
#include <stdio.h>
class CBase
{
public:
CBase();
virtual ~CBase();
void Fun1(int n);
void Fun2(int n);
void Fun3(int n);
};
CBase::CBase(){};
CBase::~CBase(){};
void CBase::Fun1(int n)
{
printf("FUN1 : Hello World! %d\n",n);
};
void CBase::Fun2(int n)
{
printf("FUN2 : Hello World! %d\n",n);
};
void CBase::Fun3(int n)
{
printf("FUN3 : Hello World! %d\n",n);
};
typedef void (CBase::*BaseMemberFn)(int);
#define CallMemberFun(object,ptrToMember) ((object).*(ptrToMember))
int main(int argc, char* argv[])
{
BaseMemberFn FnArray[3]={&CBase::Fun1,&CBase::Fun2,&CBase::Fun2};
CBase b;
for(int i=0;i<3;i++) CallMemberFun(b,FnArray[i])(i);
getchar();
return 0;
}Top
16 楼cker(〖烟波浩淼三千里、人鬼殊途五百年〗)回复于 2001-09-24 23:56:18 得分 0
用static 申明此成员函数也是可行的办法。
Top
17 楼qqchen79(知秋一叶)回复于 2001-09-25 03:17:40 得分 100
是你说不择手段的!我就不管了。
对一下程序:
1. member function must not be virtual.
2. member function cannot depend on value of this.
3. prepare_cast 只是用来定义变量,如果愿意,把它并在第二个define里。
4. 没法保证不出错。
#include "stdafx.h"
#include <iostream>
using namespace std;
#define prepare_cast char _strange_cast_buf[64]
#define strange_cast(t, f) (sprintf(_strange_cast_buf, "%d", f), (t)atoi(_strange_cast_buf));
struct A
{
void foo() {
cout << "Class A::foo()" << endl;
}
};
typedef void (*FUNC)(void);
int main()
{
prepare_cast;
FUNC func = strange_cast(FUNC, A::foo);
func();
return 0;
}
Top
18 楼sevecol(sevecol.blogone.net)回复于 2001-09-25 09:05:01 得分 0
to cker:你的方法是其实只是表面上不是调用指向成员函数的指针,实际上还是调用了,用static那就不是成员函数了
to qqchen79:方法不错,虽然没有调试,但是我觉得有问题,你的函数里面没有调用struct里面
数据,也就是说你的函数不依赖于实例,但是如果依赖实例呢,那用你的方法我觉得有问题
我的想法是将typedef void(*FUNC)();改为typedef void (*FUNC)(A&);应该OK
Top
19 楼cber(cber)回复于 2001-09-25 09:17:05 得分 0
to sevecol:用一个function object来代替函数指针没有什么不好的。如果非要用函数指针之间的转换,我也没有办法:(Top
20 楼sevecol(sevecol.blogone.net)回复于 2001-09-25 09:34:40 得分 0
to cber:我只是想看看还有什么好的办法,我觉得用function object来使用的话,开销会不会太大了?如果使用很多的话?Top
21 楼wilddragon(东瀛倭族自治州州长)回复于 2001-09-25 10:00:46 得分 0
哈哈Top
22 楼qqchen79(知秋一叶)回复于 2001-09-25 10:55:10 得分 0
事实上a.foo()与foo(A& a)完全不一样,前者将this放在ecx寄存器里(Intel CPU的转换),后者将a的地址放在堆栈里,所以直接的转换不可能存在(如果前汇编的话,也许能行,但也不一定符合你的要求了)Top
23 楼qqchen79(知秋一叶)回复于 2001-09-25 10:57:40 得分 0
顺便说一句,STL中有个mem_fun的adaptor,就实现了cber的方法。而且一般用functor对象不会慢。Top
24 楼sevecol(sevecol.blogone.net)回复于 2001-09-25 11:17:47 得分 0
to qqchen79:用汇编可以,我试了,谢谢你了
派分了Top
25 楼coldsea_2000(怒海风云)回复于 2001-09-25 21:23:51 得分 0
看着看着就花了眼,岂一个长字了得?Top
26 楼IAmKylix(kylix)回复于 2001-09-26 08:24:56 得分 0
为什么要用C++?Top
27 楼satanmonkey(撒旦)回复于 2001-09-26 10:20:17 得分 0
gzTop
28 楼city_tiger(都市老虎)回复于 2001-09-26 13:33:44 得分 0
VC专家答疑
http://bros4.top263.net
Top




