类成员指针
class A{
public:
int i;
int j;
int fff();
}
.......
int A::*pa;
int (A::*pf)();
A a;
pa=&a::j;
pf=&a::fff;
据说pa应理解为成员在类中的偏移量,是不是(&a.j-&a.i)?pf又该如何理解?
请用国类成员指针的老师讲讲,您在什么情况下用它们,有什么好处?
问题点数:60、回复次数:30Top
1 楼tjm()回复于 2001-08-23 01:51:36 得分 0
xiexieTop
2 楼reinly(老姜)回复于 2001-08-23 04:56:15 得分 10
一般来说上述理解是正确的,不过结构有些不合理.在使用类的时候,请尽量把数据成员包含在private中,这样可以保证类的封装性!
pf实际上是指向类成员函数的一个指针.
使用类结构的好处是:可以将实现过程与接口函数分开,实现了实现过程的隐蔽性,但是却可以通过public成员函数访问private中的数据成员,这样防止类非法修改类中的数据成员.从而给编码的可维护性带来了极大的收益Top
3 楼liu_feng_fly(笑看风云 搏击苍穹 衔日月)回复于 2001-08-23 09:04:00 得分 0
pf是fff()在vtable中的偏移量Top
4 楼chenqj(吉子)回复于 2001-08-23 09:32:15 得分 0
怎么会有vtable呢?连虚函数都没有Top
5 楼liu_feng_fly(笑看风云 搏击苍穹 衔日月)回复于 2001-08-23 09:44:03 得分 0
哦,不好意思,看错了,那就应该是fff()函数在内存中的地址Top
6 楼fsb_12345(myself)回复于 2001-08-23 09:50:23 得分 0
upTop
7 楼magicblue(小飞侠)回复于 2001-08-23 10:58:36 得分 0
写的很乱。你对类和对象的理解还不够清楚Top
8 楼LuoGD(抢第一楼)回复于 2001-08-23 12:49:10 得分 0
没用过,没什么好的。
本来就是要封装的。Top
9 楼shgciom(一条小鱼)回复于 2001-08-23 13:07:11 得分 0
偏易地址是不是不是这么理解的,该是相对实例首地址的吧?
(&a.j-&a.i)这么简单的减不太对吧?我只知道如果有虚函数肯定不对!
Top
10 楼tohigh(岁月的童话.NET)回复于 2001-08-23 13:28:28 得分 0
同意老姜。Top
11 楼wanghu(不懂就是不懂)回复于 2001-08-23 13:41:24 得分 5
用法不对亚
class A{
public:
int i;
int j;
int fff();
}
.......
int A::*pa;
int (A::*pf)();
A a;
pa=&a::j;--->pa=&A::j;
pf=&a::fff; --->pa=&A::fff;
Top
12 楼magicblue(小飞侠)回复于 2001-08-23 17:28:02 得分 0
pa=&A::j;
你这么些也不对,j属于对象不属于类,除非它是静态的
要想取得对象中的数据成员地址要用类型指针指向对象的数据成员,否则类型会出错。Top
13 楼wanghu(不懂就是不懂)回复于 2001-08-23 18:03:40 得分 0
这样写是对的,你不妨试一下。
不好意思打错了,应该是:pf=&A::fff; 或者pf=A::fff;Top
14 楼xiterator(xi)回复于 2001-08-23 18:29:56 得分 10
同意wanghu(不懂就是不懂),pa=&A::fff-->pf=&A::fff.
指向class member(除了static member function)的指针,都无法脱离对象或对象指针而引用/调用相应的class member即采用->*/.*操作符引用class member(除了static member function).对于class data member的指针其值为成员在对象布局中的offset,对于class non-virtual member指针其值为函数地址,对于class virtual member指针其值为vtable index.详见<<Inside The C++ Object Model>>Top
15 楼tjm()回复于 2001-08-23 20:26:55 得分 0
谢谢指教,我的理解更深了。应该是pa=&A::j;(是类名,不是对象名)。现在希望使用过这样指针的老师讲讲,为什么要用它?不用它似乎更简单,造出这样一个概念不会是偶然的吧。
Top
16 楼tjm()回复于 2001-08-24 20:11:15 得分 0
upTop
17 楼magicblue(小飞侠)回复于 2001-08-24 22:56:54 得分 0
to:wanghu
恩.的确可以那样...
不过以下的程序link时会出错
class A
{
public:
A(){i = 1;j = 2;}// i add a constructor so that compile success
int i;
int j;
int fff();
};
void main()
{
int A::*pa;
int (A::*pf)();
A a;
pa=&A::j;//what mean?i can not understand it
pf=&A::fff;
}
error LNK2001: unresolved external symbol "public: int __thiscall A::fff(void)" (?fff@A@@QAEHXZ)
fatal error LNK1120: 1 unresolved externals
Top
18 楼waterstony(王小石)回复于 2001-08-25 00:49:59 得分 0
up,函数没有实现体。改为int fff(){return 0;}就ok了Top
19 楼magicblue(小飞侠)回复于 2001-08-25 10:46:59 得分 5
pa=&A::j;
这种写法并不是得到j在内存中的地址,而是得到j在A中的offset
要得到真正地址必须有个对象:pa = &a.j;//这里pa类型为int*
C++对象模型里有讲
结贴了吧:)Top
20 楼tjm()回复于 2001-08-25 16:16:43 得分 0
现在希望使用过这样指针的老师讲讲,为什么要用它?不用它似乎更简单,造出这样一个概念不会是偶然的吧。
Top
21 楼magicblue(小飞侠)回复于 2001-08-25 16:46:36 得分 0
A::j;这种方法只能用在取j在类中的offset,如果想要对j赋值的话A::j;是行不通的,至于造出这样一个概念...只能说是语法规定,也符合常理Top
22 楼tiongkohlang(SDK)回复于 2001-08-25 16:57:47 得分 5
如果你不知道成员函数名,只知道它的地址,那么必须使用成员函数的指针调用这个成员函数。
mfc实现message_map的时候就是使用了类的成员函数的指针。
Top
23 楼tjm()回复于 2001-08-27 20:09:46 得分 0
waite for last oneTop
24 楼tjm()回复于 2001-08-30 23:02:22 得分 0
upTop
25 楼tjm()回复于 2001-09-03 21:13:46 得分 0
upTop
26 楼cgaga(红枫剪影)回复于 2001-09-03 22:30:58 得分 5
好多错误呢
class A{
public:
int i;
int j;
int fff();
}
int A::*pa;
int (A::*pf)();
A a;
pa=&a.j;//::是c++的开域符,它的左边必须是class或namespace
pf=&a.fff;
//使用
//获取j
int jj=a.*pa;//.*是c++的一个特殊运算符,如果有A* p的话,则需使用p->*pa;
//调用fff
(a.*pf)();
或
(pa->*pf)();
成员指针很麻烦,最好少用
Top
27 楼fsb_12345(myself)回复于 2001-09-04 10:26:47 得分 0
pf就是指向类成员函数的一个指针
同意reinly(老姜)
Top
28 楼tjm()回复于 2001-09-05 23:20:05 得分 0
谢谢指教,我现在只剩下面的问题:
谁用过类成员指针?它有什么实用价值?Top
29 楼qqchen79(知秋一叶)回复于 2001-09-05 23:28:37 得分 20
并不常用,但在STL的一个角落里可以找到例子:
对一个容器(list, vector, set...)中的所有对象,你希望调用改对象的一个方法(假设为Foo()方法),应该怎么写呢?
list<CMyClass*> mylist;
......
for_each(mylist.begin(), mylist.end(), mem_fun(&CMyClass::Foo));
这里,mem_fun的内部实现中使用了->*操作符。
其实,->*只是为了多加一层抽象的目的,是你可以将更多的选择(方法调用)参数化。Top
30 楼tjm()回复于 2001-09-06 21:29:43 得分 0
容器我不懂啊Top




