类成员函数指针

时间:2021-07-08 19:06:11
现在有个类A,定义成员函数A_fun_1,将该函数用指针传递给另外一个类B,在B类中定义了A类对象的指针,通过这个指针调用A_fun_1。

现在实例化多个类A和B,例如4个,4个A类对象和4个B类对象一一对应。但是问题出来了,在A类中跟踪A_fun_1的执行,发现每次A类的this指针都是固定的,按理说现在有4个B类对象,每个B类对象都包含一个各不相同的A类对象指针,所以A_fun_1被调用的时候,A类对象指针是变化的,但是为什么这个对象指针不变化呢?

请教。多谢。

19 个解决方案

#1


该回复于2011-04-19 11:16:43被版主删除

#2


你的代码?

#3


B中的m_pA(A的指针)应该是不一样的啊

#4


引用 3 楼 king_hhuang 的回复:
B中的m_pA(A的指针)应该是不一样的啊


是的。我在B中跟踪指向A对象的指针,是不同的。谢谢回复。也谢谢hdt,代码比较长,我看看能不能把关键的地方抽出来。

#5



#include "stdafx.h"
#include <iostream>
using namespace std;
class A{
int m_n;
public:
void test()
{
cout<<m_n<<endl;
}
A(int in):m_n(in)
{}
};
typedef void (A::*func)();
class B{
A* a;
public:
B(int b){ a=new A(b);}
void callfunc( func fun)
{
(a->*fun)();
}
};

func f1 =&A::test;
int _tmain(int argc, _TCHAR* argv[])
{

for( int i=0;i<5;i++)
{
B b1(i);
b1.callfunc(f1);
}
system("pause");
return 0;
}

这样????

#6



#include <stdio.h>
#include <iostream>
using namespace std;

class CA  
{
public:
CA() {}
void Func1()
{
char str[20];
memset(str,0,20);
sprintf(str,"this: 0x%08x",this);
cout<<str<<"\n";
}
};

class CB  
{
public:
CA* m_pA;

public:
CB() {}
};

void main()
{
CA a[4];
CB b[4];
int i=0;

for(i=0; i<4; i++)
b[i].m_pA = &a[i];

for(i=0; i<4; i++)
{
char str[20];
memset(str,0,20);
sprintf(str,"m_pA: 0x%08x",b[i].m_pA);
cout<<str<<"\n";
b[0].m_pA->Func1();
}
}


输出结果:
m_pA: 0x0012ff7c
this: 0x0012ff7c
m_pA: 0x0012ff7d
this: 0x0012ff7c
m_pA: 0x0012ff7e
this: 0x0012ff7c
m_pA: 0x0012ff7f
this: 0x0012ff7c
Press any key to continue

确实是一样的

#7


不好意思上面搞错了


#include <stdio.h>
#include <iostream>
using namespace std;

class CA  
{
public:
CA() {}
void Func1()
{
char str[20];
memset(str,0,20);
sprintf(str,"this: 0x%08x",this);
cout<<str<<"\n";
}
};

class CB  
{
public:
CA* m_pA;

public:
CB() {}
};

void main()
{
CA a[4];
CB b[4];
int i=0;

for(i=0; i<4; i++)
b[i].m_pA = &a[i];

for(i=0; i<4; i++)
{
char str[20];
memset(str,0,20);
sprintf(str,"m_pA: 0x%08x",b[i].m_pA);
cout<<str<<"\n";
b[i].m_pA->Func1();
}
}


输出:
m_pA: 0x0012ff7c
this: 0x0012ff7c
m_pA: 0x0012ff7d
this: 0x0012ff7d
m_pA: 0x0012ff7e
this: 0x0012ff7e
m_pA: 0x0012ff7f
this: 0x0012ff7f
Press any key to continue

不一样的

#8


class CSDIAnalyze; //类A
typedef void (CSDIAnalyze::*pStaticBlackFrameDetect)(bool static_frame, bool black_frame, int BlackLastFrames, int StaticLastFrames);

这个是类A(CSDIAnalyze)的成员函数:
void static_black_frame_detect(bool static_frame, bool black_frame, int BlackLastFrames, int StaticLastFrames);//函数太长就不贴了

类B中有A对象指针和成员函数指针:
CSDIAnalyze *pCSDIAnalyze;
pStaticBlackFrameDetect  my_static_black_detect;

在将A对象指针和成员函数地址复制给B类后,调用A成员函数:
(pCSDIAnalyze->*my_static_black_detect)(static_frame, black_frame, BlackLastFrames, StaticLastFrames); //在这里设置断点

现在在上面的断点处发现,pCSDIAnalyze是一个固定的值,同时在A类的static_black_frame_detect()函数内跟踪发现,A类的this指针也是不变的。

谢谢。


#9


引用 7 楼 king_hhuang 的回复:
不好意思上面搞错了

C/C++ code

#include <stdio.h>
#include <iostream>
using namespace std;

class CA  
{
public:
    CA() {}
    void Func1()
    {
        char str[20];
        memset(str,0,20);
        ……


非常感谢。我再看看你的代码。

#10


在将A对象指针和成员函数地址复制给B类后

看看你这个有没有复制对,你是不是把同一个A复制给了4个B的实例啊?

#11


现在在上面的断点处发现, pCSDIAnalyze是一个固定的值,同时在A类的static_black_frame_detect()函数内跟踪发现,A类的this指针也是不变的。
===================
 赋给 B类 中A类的指针时 ,应该有问题

#12


还是把你的代码贴出来吧

#13


引用 8 楼 alexander_david 的回复:
class CSDIAnalyze; //类A
typedef void (CSDIAnalyze::*pStaticBlackFrameDetect)(bool static_frame, bool black_frame, int BlackLastFrames, int StaticLastFrames);

这个是类A(CSDIAnalyze)的成员函数:
void static……

搞这么复杂
你不就是想在B中通过A的指针pA调用A_fun_1么
没必要复制函数地址吧

#14


这个程序是基于dshow框架。B类是自己写的一个filter,从dshow自带的dump范例修改过来的。类A是主程序中的一个类,所以采用这个别扭的类成员函数指针的方式。

跟踪类B发现,A对象指针的确正确传递过来了,是4个,但是不知道为什么后面调用的时候老是那一个。

多谢各位。

#15


class A;
typedef void (A::*pfun)();

class A
{
public:
void fun()
{
printf("this=0x%x\n", this);
}
};

class B
{
public:
A *pA;
pfun A_fun;
};


int _tmain(int argc, _TCHAR* argv[])
{
A a[4];
B b[4];
int i;

for(i=0; i<4; i++)
{
b[i].pA=&a[i];
b[i].A_fun=&A::fun;
}

for(i=0; i<4; i++)
{
(b[i].pA->*b[i].A_fun)();
}

return 0;
}

这个代码的输出就是:
this=0x12ff60;
this=0x12ff61;
this=0x12ff62;
this=0x12ff63;

但是不知道为什么那个就不行?

#16


然后跟踪CDumpInputPin::Receive(),这个是上面说的类B,在这个函数内跟踪pCSDIAnalyze,发现这个指针在两个数值变化,但是应该是4个才对。头大,头大的很。这个函数是接收数据的。

#17


for(i=0; i<4; i++)
{
(b[i].pA->*b[i].A_fun)();
}

这个改成
for(i=0; i<4; i++)
{
(b[i].pA->*b[0].A_fun)();
}

都没关系

但是如果改成这样

for(i=0; i<4; i++)
{
(b[0].pA->*b[i].A_fun)();
}
就会出现地址一样

所以你还是检查一下你的b[i],下标是不是搞错了,弄成了同一个

#18


to King_hhuang

实际的代码不是这样的,不是在b的外部调用的,而是在b的内部调用的,就是在b的成员函数内部通过函数指针调用,所以不会出现老是调用b[0]的情况。多谢。

#19


问题找出来了。

是在上级函数中有个判断,有些通道不满足这个条件,就提前退出了,所以就没有调用这个函数了。

不好意思,耽误大家时间了。谢谢各位热心。

#1


该回复于2011-04-19 11:16:43被版主删除

#2


你的代码?

#3


B中的m_pA(A的指针)应该是不一样的啊

#4


引用 3 楼 king_hhuang 的回复:
B中的m_pA(A的指针)应该是不一样的啊


是的。我在B中跟踪指向A对象的指针,是不同的。谢谢回复。也谢谢hdt,代码比较长,我看看能不能把关键的地方抽出来。

#5



#include "stdafx.h"
#include <iostream>
using namespace std;
class A{
int m_n;
public:
void test()
{
cout<<m_n<<endl;
}
A(int in):m_n(in)
{}
};
typedef void (A::*func)();
class B{
A* a;
public:
B(int b){ a=new A(b);}
void callfunc( func fun)
{
(a->*fun)();
}
};

func f1 =&A::test;
int _tmain(int argc, _TCHAR* argv[])
{

for( int i=0;i<5;i++)
{
B b1(i);
b1.callfunc(f1);
}
system("pause");
return 0;
}

这样????

#6



#include <stdio.h>
#include <iostream>
using namespace std;

class CA  
{
public:
CA() {}
void Func1()
{
char str[20];
memset(str,0,20);
sprintf(str,"this: 0x%08x",this);
cout<<str<<"\n";
}
};

class CB  
{
public:
CA* m_pA;

public:
CB() {}
};

void main()
{
CA a[4];
CB b[4];
int i=0;

for(i=0; i<4; i++)
b[i].m_pA = &a[i];

for(i=0; i<4; i++)
{
char str[20];
memset(str,0,20);
sprintf(str,"m_pA: 0x%08x",b[i].m_pA);
cout<<str<<"\n";
b[0].m_pA->Func1();
}
}


输出结果:
m_pA: 0x0012ff7c
this: 0x0012ff7c
m_pA: 0x0012ff7d
this: 0x0012ff7c
m_pA: 0x0012ff7e
this: 0x0012ff7c
m_pA: 0x0012ff7f
this: 0x0012ff7c
Press any key to continue

确实是一样的

#7


不好意思上面搞错了


#include <stdio.h>
#include <iostream>
using namespace std;

class CA  
{
public:
CA() {}
void Func1()
{
char str[20];
memset(str,0,20);
sprintf(str,"this: 0x%08x",this);
cout<<str<<"\n";
}
};

class CB  
{
public:
CA* m_pA;

public:
CB() {}
};

void main()
{
CA a[4];
CB b[4];
int i=0;

for(i=0; i<4; i++)
b[i].m_pA = &a[i];

for(i=0; i<4; i++)
{
char str[20];
memset(str,0,20);
sprintf(str,"m_pA: 0x%08x",b[i].m_pA);
cout<<str<<"\n";
b[i].m_pA->Func1();
}
}


输出:
m_pA: 0x0012ff7c
this: 0x0012ff7c
m_pA: 0x0012ff7d
this: 0x0012ff7d
m_pA: 0x0012ff7e
this: 0x0012ff7e
m_pA: 0x0012ff7f
this: 0x0012ff7f
Press any key to continue

不一样的

#8


class CSDIAnalyze; //类A
typedef void (CSDIAnalyze::*pStaticBlackFrameDetect)(bool static_frame, bool black_frame, int BlackLastFrames, int StaticLastFrames);

这个是类A(CSDIAnalyze)的成员函数:
void static_black_frame_detect(bool static_frame, bool black_frame, int BlackLastFrames, int StaticLastFrames);//函数太长就不贴了

类B中有A对象指针和成员函数指针:
CSDIAnalyze *pCSDIAnalyze;
pStaticBlackFrameDetect  my_static_black_detect;

在将A对象指针和成员函数地址复制给B类后,调用A成员函数:
(pCSDIAnalyze->*my_static_black_detect)(static_frame, black_frame, BlackLastFrames, StaticLastFrames); //在这里设置断点

现在在上面的断点处发现,pCSDIAnalyze是一个固定的值,同时在A类的static_black_frame_detect()函数内跟踪发现,A类的this指针也是不变的。

谢谢。


#9


引用 7 楼 king_hhuang 的回复:
不好意思上面搞错了

C/C++ code

#include <stdio.h>
#include <iostream>
using namespace std;

class CA  
{
public:
    CA() {}
    void Func1()
    {
        char str[20];
        memset(str,0,20);
        ……


非常感谢。我再看看你的代码。

#10


在将A对象指针和成员函数地址复制给B类后

看看你这个有没有复制对,你是不是把同一个A复制给了4个B的实例啊?

#11


现在在上面的断点处发现, pCSDIAnalyze是一个固定的值,同时在A类的static_black_frame_detect()函数内跟踪发现,A类的this指针也是不变的。
===================
 赋给 B类 中A类的指针时 ,应该有问题

#12


还是把你的代码贴出来吧

#13


引用 8 楼 alexander_david 的回复:
class CSDIAnalyze; //类A
typedef void (CSDIAnalyze::*pStaticBlackFrameDetect)(bool static_frame, bool black_frame, int BlackLastFrames, int StaticLastFrames);

这个是类A(CSDIAnalyze)的成员函数:
void static……

搞这么复杂
你不就是想在B中通过A的指针pA调用A_fun_1么
没必要复制函数地址吧

#14


这个程序是基于dshow框架。B类是自己写的一个filter,从dshow自带的dump范例修改过来的。类A是主程序中的一个类,所以采用这个别扭的类成员函数指针的方式。

跟踪类B发现,A对象指针的确正确传递过来了,是4个,但是不知道为什么后面调用的时候老是那一个。

多谢各位。

#15


class A;
typedef void (A::*pfun)();

class A
{
public:
void fun()
{
printf("this=0x%x\n", this);
}
};

class B
{
public:
A *pA;
pfun A_fun;
};


int _tmain(int argc, _TCHAR* argv[])
{
A a[4];
B b[4];
int i;

for(i=0; i<4; i++)
{
b[i].pA=&a[i];
b[i].A_fun=&A::fun;
}

for(i=0; i<4; i++)
{
(b[i].pA->*b[i].A_fun)();
}

return 0;
}

这个代码的输出就是:
this=0x12ff60;
this=0x12ff61;
this=0x12ff62;
this=0x12ff63;

但是不知道为什么那个就不行?

#16


然后跟踪CDumpInputPin::Receive(),这个是上面说的类B,在这个函数内跟踪pCSDIAnalyze,发现这个指针在两个数值变化,但是应该是4个才对。头大,头大的很。这个函数是接收数据的。

#17


for(i=0; i<4; i++)
{
(b[i].pA->*b[i].A_fun)();
}

这个改成
for(i=0; i<4; i++)
{
(b[i].pA->*b[0].A_fun)();
}

都没关系

但是如果改成这样

for(i=0; i<4; i++)
{
(b[0].pA->*b[i].A_fun)();
}
就会出现地址一样

所以你还是检查一下你的b[i],下标是不是搞错了,弄成了同一个

#18


to King_hhuang

实际的代码不是这样的,不是在b的外部调用的,而是在b的内部调用的,就是在b的成员函数内部通过函数指针调用,所以不会出现老是调用b[0]的情况。多谢。

#19


问题找出来了。

是在上级函数中有个判断,有些通道不满足这个条件,就提前退出了,所以就没有调用这个函数了。

不好意思,耽误大家时间了。谢谢各位热心。

#20