CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

c++编程思想中的重载操作符一节中关于灵巧指针(->)有些不理解

楼主fresh_(fresh_)2001-05-23 09:36:00 在 VC/MFC / 基础类 提问

 
   
  class   obj{  
  ...  
  public:  
  void   f(){...};  
  viod   g(){...};  
  };  
   
  class   sp{  
  ...  
  obj*   objector->(){                                       //重载->操作符  
  ...}  
  };  
   
  main()  
  {  
  sp   SP;  
  SP->f();  
  }  
  上面主程序中SP->调用重载操作符后,返回的应该是个指针(指向obj对象),这个指针要调用f()成员是否应该再来一个“->”?即:SP->->f(). 问题点数:120、回复次数:22Top

1 楼coolxiao(coolxiao)回复于 2001-05-23 09:48:00 得分 0

我估计这时候c++会先匹配了系统运算符   Point->Member,因为你重载后的->只是单目运算,我想不会先匹配的。具体情况我也没有试   过,最后自己动手做一做Top

2 楼coolxiao(coolxiao)回复于 2001-05-23 09:49:00 得分 20

sorry,看错了,SP不是指针,那我说错了=)Top

3 楼wagnerwash()回复于 2001-05-23 10:27:00 得分 0

->是2元操作符,你重载的语法不对!Top

4 楼sequoia_96(牛琴乱弹)回复于 2001-05-23 10:30:00 得分 0

我想因该不能编译通过吧,像楼上说的。具体我也没试过,最好自己编译以下Top

5 楼eggplant(拉拉)回复于 2001-05-23 11:27:00 得分 20

class   CA  
  {  
  public:  
      virtual   void   func1{}();  
  }  
   
  class   CB  
  {  
      public:  
      CB(CA*   p){m_p=p;}  
      CA*   operator   ->(){return   m_p;}  
      private:  
      CA*   m_p;  
  }  
   
  一个使用例子:  
  CA*   pa=   new   CA;  
  CB*   pb=   new   CB(pa);  
  CA*   pa2=   pb->operator   ->();  
   
   
  下面是MSDN的说明:  
   
  Class-Member   Access  
  Class-member   access   can   be   controlled   by   overloading   the   member-selection   operator   (–>).   This   operator   is   considered   a   unary   operator   in   this   usage,   and   the   overloaded   operator   function   must   be   a   class   member   function.   Therefore,   the   declaration   for   such   a   function   is:    
   
  class-type   *operator–>()  
   
  where   class-type   is   the   name   of   the   class   to   which   this   operator   belongs.   The   member-selection   operator   function   must   be   a   nonstatic   member   function.  
   
  This   operator   is   used   (often   in   conjunction   with   the   pointer-dereference   operator)   to   implement   “smart   pointers”   that   validate   pointers   prior   to   dereference   or   count   usage.  
   
  The   .   member-selector   operator   cannot   be   overloaded.  
  Top

6 楼liu_feng_fly(笑看风云 搏击苍穹 衔日月)回复于 2001-05-23 11:56:00 得分 0

??Top

7 楼jy(树,路)回复于 2001-05-23 12:25:00 得分 0

典型的实现是COM的智能接口指针(Smart   Interface   Pointers)。  
  关于这个,可以参阅MSDN中标题为“Calling   COM   Objects   with   Smart   Interface   Pointers”的文章,我相信看完就会明白了。  
   
  另外,千真万确:->是一个一元操作符。前面eggplant的语法是正确的。Top

8 楼fresh_(fresh_)回复于 2001-05-23 16:37:00 得分 0

to   eggplant:  
  期待你将例子做下去。  
  你的使用例子:  
  CA*   pa=   new   CA;  
  CB*   pb=   new   CB(pa);  
  CA*   pa2=   pb->operator   ->();  
  如果接下去要使用pa2的func1,该怎么写?是这样吗?  
  CA*   pa=   new   CA;  
  CB*   pb=   new   CB(pa);  
  CA*   pa2=   pb->operator   ->();  
  pa2->func1();  
  回到我的问题上,如果不定义pa2,而直接使用pb->operator   ->()返回的临时指针直接调用func1,即:将第3、4行合并,该变成什么样?  
  1)pb->operator->()->func1();     还是     2)pb->operator->func1();      
  我觉得因该是1)  
  可书上是2)(c++编程思想p214,line   3或4)  
  所以来此向大家请教。  
   
   
   
  Top

9 楼jy(树,路)回复于 2001-05-24 03:38:00 得分 60

应该是pb->operator->()->func1();  
  你是对的。  
   
  2)是肯定错的。不可能产生出那样的语序。  
   
  你如果真的想使用smart机制,应该这样:  
  CB   b(pa);  
  b->func1();  
   
  ///////////////////////////////////////////////////////////  
  是的,b是一个对象,而不是真正的指针;  
  把b当作一个指针来使用,正是重载->的目的。  
  这样,才体现出C++之强大:紧凑,直观(在理解的基础上,这是直观的)。试想焉能不为之着魔?  
   
   
  COM对象保留一个引用计数,所以使用灵巧指针机制对计数进行维护。  
   
   
  (c++编程思想p214,line   3或4)  
  抱歉我还没看这书,但是,你确信?我不大信它这样子犯错。  
  Top

10 楼jy(树,路)回复于 2001-05-24 03:49:00 得分 0

想想自己说得太满,呵呵,赶紧验证了一下,现在郑重宣布,我的说法是正确的,你的那个TICA书是错的。Top

11 楼fresh_(fresh_)回复于 2001-05-24 09:50:00 得分 0

这本书上几乎全是这样使用,(如p309,倒数第5行等),难道全错了?我觉得不太可能,在程序中将两种写法都用了一下,效果居然一样。真是奇怪,难道1)、2)两种写法等价?打死我也不信Top

12 楼jy(树,路)回复于 2001-05-24 10:49:00 得分 0

"这本书上几乎全是这样使用"是怎么个用法?贴来看看。  
   
   
  “在程序中将两种写法都用了一下,效果居然一样。真是奇怪,难道1)、2)两种写法等价?”是指  
  “pb->operator->()->func1();     还是     2)pb->operator->func1();”?  
  我怀疑,因为2)连编译都不能,也不应该通过。Top

13 楼coolxiao(coolxiao)回复于 2001-05-24 13:02:00 得分 0

我看过关于smart   pointer的那篇文章,其中有一句“Therefore,   SIDraw–>Draw()   from   the   previous   examples   results   in   a   call   to   SIDraw.m_pI->Draw().   SIDraw   delegates   the   Draw   call   to   the   interface   pointed   to   by   m_pI.   ”为什么  
  SIDraw->Draw()会等价于SIDraw.m_pI->Draw(),而->的重载定义是返回一个指针啊,要是没有看过这篇文章的话,我会用(SIDraw->)->fun(),但是不能通过编译的,难道这是C++的特殊规则吗?Top

14 楼jy(树,路)回复于 2001-05-24 13:07:00 得分 0

原来全都还没明白!!!  
   
   
  你如果真的想使用smart机制,应该这样:  
  CB   b(pa);  
  b->func1();   //b不是指针类型,而是CB对象的实例!!但是可以象指针一样工作,因为CB被进行了->重载  
   
  ///////////////////////////////////////////////////////////  
  是的,b是一个对象,而不是真正的指针;  
  把b当作一个指针来使用,正是重载->的目的。  
  这样,才体现出C++之强大:紧凑,直观(在理解的基础上,这是直观的)。试想焉能不为之着魔?  
   
   
  Top

15 楼jy(树,路)回复于 2001-05-24 13:22:00 得分 0

->的重载,被解释为对象实例的类型转变。  
   
  同样通过重载进行转变的,还有!、(),例如  
  class   a   {  
  public:  
  bool   operator   !()   {   return   false;   }  
  bool   operator   ()   {   return   true;   }  
  };  
   
  a   A;  
   
  ...  
  if(A){  
  }  
  if(!A){  
  }  
   
  Top

16 楼jy(树,路)回复于 2001-05-24 13:24:00 得分 0

应该是bool   operator   ()()   {   return   true;   }  
  Top

17 楼coolxiao(coolxiao)回复于 2001-05-24 13:35:00 得分 0

      =)不要说我顽固啊,不过我还想问一下,没错(A)确实是返回TRUE,!(A)返回FALSE,那么说b->是不是应该返回一个pointer呢?但为什么不能这样用?  
        Top

18 楼fresh_(fresh_)回复于 2001-05-24 14:00:00 得分 0

to   jy  
  谢谢,请继续不厌其烦的替我们讲解清楚。  
   
  to   coolxiao  
  终于有人有我一样的问题了。“那么说b->是不是应该返回一个pointer呢?”我正是想追问这个。Top

19 楼jy(树,路)回复于 2001-05-24 14:34:00 得分 0

...  
  说起来,返回是一个指针,没错;但是...  
   
  :)  
  我承认,我的能力有限,无法解释清楚,这是我没有出书的原因,:P  
  不可以->->,而是->或者->()->  
  这算不算是一种语感?  
   
   
  我觉得,看这个问题,是一种方法问题。  
  一定要精确表述的话,(b->是不是应该返回一个pointer)是错误的,你只能说,(b.operator->()返回一个指针),所以,早前我指出(b.oerator->())->func()的语法才是正确的。注意,我用括号限定了b.operator->()来加强你对它的认识。  
  b->根本不是一个完整的表达式,更加谈不上具有返回值了。  
  Top

20 楼kalling(kalling)回复于 2001-05-24 14:41:00 得分 20

实际的例子:  
  我正好在做word的控制,从一个type   library导入了一个包装类_Application  
  如_Appliction   word;  
  既可以用word.QueryInterface(),又可以用word->Documents();  
  这就是smart   pointerTop

21 楼coolxiao(coolxiao)回复于 2001-05-24 16:03:00 得分 0

那就奇怪了,既然->是单目运算符,为什么   b->是错误的表达式呢?  
  这样说int   a=1,b;   b=a++;不也不成立吗?因为我对smart   pointer没有深入的了解,只是从c++重载运算符的规则出发来想问题的,是不是我的理解有问题呢?  
  看来fresh_(fresh_)你要加点分了,毕竟jy(树)对付我们也很烦的了,是不?=)  
  如果帖子超过25个回复,那我再开一帖帮高手们加分,只求一个合理解释而已!Top

22 楼jy(树,路)回复于 2001-05-24 17:34:00 得分 0

应该说我黔驴技穷才对,呵呵。  
  coolxiao这么追究对我也有好处,我也可以认真思考一番。  
  我可没有对付的意思:)  
   
   
  那么,->是不是单目呢?  
  我早前的理解是从它的特性着手的,把它视为一种特例。因为->的功能是为了返回一个“指针性质”的成员命名(Names),所以,尽管其后带有成员限定名,我们仍然当作是单目的运算符。  
  反过来,从operator语法上也可以反推这一点。  
  但,这当然不容易让人信服。  
   
  实际上如何呢?实际上,->没有目的概念,他既非单目,也非双目,。。  
  ->在C++中是一种扩展的运算符,扩展表示这是一种类型转换运算符(type   conversion   operator)。【注:扩展理解见结尾的解释】  
  (好了,现在我资料在手,可不怕你们了)  
  在C++的手册里,->被分属成member-selection   operator(正解!不是单目,不是双目,我就是我!),这和类型转换运算符的概念没有冲突,我是这么理解的。  
   
  好,再来,接着解释  
  其语法要求为:  
  postfix-expression   :  
  primary-expression  
  postfix-expression   [   expression   ]  
  postfix-expression   (   expression-listopt   )  
  simple-type-name   (   expression-listopt   )  
  postfix-expression   .   name  
  postfix-expression   ->   name  
  postfix-expression   ++  
  postfix-expression   --  
  仔细研究这个语法表述,你可以明确的看出为什么b->不完整,a++却完整。  
   
   
  好了,收个尾:  
  我明确->operator的函数表达方法应该是:  
  operator   type-name()  
  我强调把->理解为一个类型转换运算符(type   conversion   operator),这样,推而广之,你可以轻易写出一系列的运算符重载而不求人:  
  operator   int   ();  
  operator   ->   ();  
  operator   char*   ();  
  operator   LPCTSTR   ();  
  operator   HWND   ();  
  ...  
   
  Top

相关问题

  • 操作符重载
  • 操作符重载
  • 操作符重载
  • C/C++编程,关于操作符重载问题~~~~~~???
  • C++专家请进,操作符重载问题
  • C++模板类(template <class T> class myclass)中操作符重载问题
  • 小问题:C++ 重载赋值操作符的两种方式?
  • [求助] c++关于操作符重载的问题
  • 关于操作符重载。
  • 有关操作符重载

关键词

  • c++
  • c++编程
  • 指针
  • pb
  • 语法
  • smart
  • ca
  • 转换
  • 重载
  • 运算符

得分解答快速导航

  • 帖主:fresh_
  • coolxiao
  • eggplant
  • jy
  • kalling

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

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