CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

麻烦看看这几种对成员函数的调用有什么不同

楼主dragonQ(红河)2004-04-04 11:35:04 在 C/C++ / C++ 语言 提问

小弟初识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

相关问题

  • 调用char *成员函数
  • php类在成员函数中怎么调用另一个成员函数?
  • 怎样在一个成员函数调用另一个成员函数?
  • 一个类的成员函数可以调用另一个成员函数吗?
  • 关于成员函数声明时调用其它成员函数的问题
  • 如何在静态成员函数中调用非静态成员函数?
  • 请问如何在static成员函数中调用非static成员函数?
  • 虚函数以及非虚函数的调用,对象是怎么调用成员函数的?
  • 调用静态数据成员和成员函数
  • 函数调用

关键词

  • 函数
  • 指针
  • 内存
  • 文件
  • virtual
  • 调用
  • func
  • 静态
  • 成员
  • 对象

得分解答快速导航

  • 帖主:dragonQ
  • angelo23
  • Jinhao
  • b_horse

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo