麻烦看看这几种对成员函数的调用有什么不同
小弟初识C++,对于成员函数的调用有些不明白,请高手赐教!
1:
Class1 o1;
o1.func(); //func为Class1成员函数
2:
Class1* o2;
o2->func();
3:
typedef void (Class1::*PType) ();
PType pt = &Class1::func;
Class1* o3;
o3->*pt;
4:
Class1::func(); //这里假设func为静态成员函数
请问以上4种调用方式有何不同?不要告诉我只是写法不同,呵呵...
也请不要大谈静态成员函数是怎么回事,对于静态成员函数,我只想知道有什么优点!
谢谢!
问题点数:100、回复次数:19Top
1 楼angelo23(angelo)回复于 2004-04-04 11:50:49 得分 30
先把第二种改一下:
Class1* o2;
o2 = new Class1;
o2->func();
第三种也要如法修改
其实前三种确实只是写法不同而已,内部的实现都是一样的,大同小异而已。func()实际接收一个参数,所谓的this指针,也就是调用它的对象的地址. 而静态成员函数不接受this指针,即使你用一个对象去调用它,实际也是和 Class1::func();等价的Top
2 楼angelo23(angelo)回复于 2004-04-04 11:54:53 得分 0
o1.func();
---》
func(&o1);
o2->func();
---》
func(o2);
o3->*pt;
---》
(pt)(o3);
而第四种就像调用一个普通的函数一样,取它的地址也是得到一般的函数地址(实际内存中的地址,和指向成员函数的指针不同)Top
3 楼Jinhao(辣子鸡丁·GAME就这样OVER了)回复于 2004-04-04 11:56:07 得分 30
确实是写法不同
1、使用于
ol是实例对象,func是成员函数名
2、使用于
o2是class A的指针,func是成员函数名
3、使用于
o3是class A的指针,pt是一个指向成员的指针,在这里pt是成员函数指针
所以应该
typedef void (Class1::*PType) ();
PType pt = &Class1::func;
Class1* o3;
(o3->*pt)(); //要知道()的作用是什么
4、使用于func是静态成员,静态成员还可以像下面那样调用
o1.func();也行
o2->func();也行Top
4 楼Jinhao(辣子鸡丁·GAME就这样OVER了)回复于 2004-04-04 11:59:48 得分 0
如果知道静态成员函数是怎么会事,那他就没什么优点
除了能访问静态成员,其余的“什么都不能干”Top
5 楼newegg2002(同志们,同胞们,大学的四年,是扎实基础的四年!!)回复于 2004-04-04 12:30:03 得分 0
1,2,4,见得多了,,3还没有见到过。。学习吧。。不过还是不完全明白。。
//要知道()的作用是什么
那它的作用到底是什么?
问题很菜,,不过还是想知道。Top
6 楼angelo23(angelo)回复于 2004-04-04 12:36:51 得分 0
好比pf是一个一般的函数指针
void foo(){}
void (*pf)() = &foo;
*pf;
你光写一个*pf是没有用的,只是计算foo函数的地址,并不调用,函数调用一定要有()的。所以你得写(*pf)();
一样的道理……Top
7 楼dragonQ(红河)回复于 2004-04-04 12:46:05 得分 0
看来效率方面没有什么差别啊,只是不同的表示,至于1和2,是否仅仅因个人爱好而随意选择
To: newegg2002(天生我菜有X用)
在后面的括号里传递的是实参,因为我的例子里没有写参数,所以只写了一个空括号Top
8 楼happlyman(广瑞)回复于 2004-04-04 12:59:11 得分 0
大家都回答的很全了!!!Top
9 楼jp1984(mathfrog)回复于 2004-04-04 13:00:54 得分 0
1:
Class1 o1;
o1.func(); //func为Class1成员函数
2:
Class1* o2;
o2->func();
/*这两种形式是一样的,只是表达方式不一样 而已。。通俗的说点操作运算符代表什么什么的什么,所以o1.func()就是class1的对象o1的成员函数func 。。下面用-> 定义一个类型为class* 型对象o2,可用所以可用指针特有的->来 调用func()...*/
4。Class1::func(); //这里假设func为静态成员函数
// 你都说了func为静态的成员函数了,这就是掉用类静态成员函数的语法。因为静态函数是不接受this指针的(即指向当前对象的指针),所以就算你用对象来调用,跟直接用::调用是一样的饿。
//*love myj*Top
10 楼b_horse(盲马)回复于 2004-04-04 13:16:29 得分 40
1:
Class1 o1;
o1.func(); //func为Class1成员函数
*对象的这种使用方法,是Object Based(基于对象)的使用方法,在这种情况下,o1将是一种“静态”的运行方式;func的绑定会在编译期完成,即使它是virtual function;这是一种“平凡”的使用方法,因而,如果func是inline的话,compiler极可能乐于为你将其展开。
2:
Class1* o2;
o2->func();
*对象的这种使用方法,是Object Oriented(基于对象)的使用方法,在这种情况下,o1将是一种“动态”的运行方式;如果func被标以virtual,则“多态”将在此展现;当然,为此我们必须付出一些代价,它将比OB的用法慢一些,嗯,如果func是inline的话,可能被compiler所忽略。
3:
typedef void (Class1::*PType) ();
PType pt = &Class1::func;
*pt在此处将存储类Class1中方法func在内存中的地址,但请注意它只是记载了一个位置而已,没有对象的配合,是不能单独用来调用该方法(func)的;
Class1* o3;
o3->*pt;
*这也是一种“动态”的运行方式(与2基本一致),如果func被定义为virtual,那么“多态”的性质也将在此得以展现;
4:
Class1::func(); //这里假设func为静态成员函数
*静态函数将拥有自己在内存中的地址,但比成员函数的地址相比,它具有可以独立使用的特点,这个特征时它能充当callback函数,呵呵,在消息映射的设计框架中,它可以发挥大用处!
Top
11 楼b_horse(盲马)回复于 2004-04-04 13:18:49 得分 0
抱歉,2中的Object Oriented 是面向对象的使用方法;Top
12 楼b_horse(盲马)回复于 2004-04-04 13:28:18 得分 0
还需要对3进行一下补充:
当func是个virtual function时,pt的值将可能是func在虚拟函数标准中的索引值(视编译器不同,可能有所差异),而不是个内存地址;呵呵,所以这么多的“间接性”给我们的提示是:它的调用效率可能更低!Top
13 楼angelo23(angelo)回复于 2004-04-04 14:29:51 得分 0
看来效率方面没有什么差别啊,只是不同的表示,至于1和2,是否仅仅因个人爱好而随意选择
-------------------------------------------------------------------
效率上还是略有区别的(1,2和3比较而言,3的效率可能会低一点,但优化后无甚区别)
*对象的这种使用方法,是Object Oriented(基于对象)的使用方法,在这种情况下,o1将是一种“动态”的运行方式;如果func被标以virtual,则“多态”将在此展现;当然,为此我们必须付出一些代价,它将比OB的用法慢一些,
-----------------------------
盲马说的太绝对了,就这个例子而言,如果没有虚函数的话谈不上OO或者动态或者多态,和一般的基于对象无异Top
14 楼sharkhuang(走吧走吧!人总会慢慢长大~)回复于 2004-04-04 16:15:17 得分 0
感觉在效率方面是一样的.Top
15 楼angelo23(angelo)回复于 2004-04-04 17:00:36 得分 0
哦,如果不涉及虚函数或者虚拟继承的话确实差不多Top
16 楼b_horse(盲马)回复于 2004-04-04 18:46:38 得分 0
to angelo23(angelo):
我想您误解我的意思了,我在此所说的“动态”和你所指的不太一样。我的意思是当使用对象直接访问成员时,其地址在compile期就已确定了,是为“静态”;而使用对象指针,其对象的内存位置在堆里,只要在运行期才能确定,是为“动态”。Top
17 楼wdslhr(我爱西湖)回复于 2004-04-04 22:11:04 得分 0
在用动态连接库时,当要生成.DLL文件时,有的书上说要加入.def文件,不知.def文件怎么生成呀???Top
18 楼freefalcon(心宇—消失中...)回复于 2004-04-04 22:31:56 得分 0
to wdslhr(编程渴求者)
def不是必需的
导出函数的方法有多种,def是其中的一种,微软提供的__declspec(dllexport)是另一种,后者比前者使用起来更方便一些
def都是手工添加,它有其固定格式,具体细节可参看msdnTop
19 楼bshaozi(俺们那噶不学c!)回复于 2004-04-04 22:53:52 得分 0
简单的说4种都是调用类的成员函数;
第一种和第二种都是通过哪个具体对象调用的函数,就对其哪个对象的成员进行作用;
而第三种和第一第二种作用一样就是形式不一样~
在调用函数的时候用的是函数的指针;
就如int *a;
int b=5;
a=&5;
在用a所指向的值应该用*a一样~
和第四种是一个静态函数;他只能对静态变量起作用;
因为他是静态的~所以在用的时候应该指明是哪个类;且经过做用后整个类的对象的那些静态变量全改变Top




