免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 4157 | 回复: 22
打印 上一主题 下一主题

[C++] c++函数重载问题讨论!! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-11-03 19:57 |只看该作者 |倒序浏览
下面的“=”函数重载是错的,但只要把string operator=(const string s )改成string &operator=(const string &s )就对了。想不通为什么非要加&。
#include <iostream.h>;
   #include <string.h>;
  // using namespace std;
   class string
   {
                char *ptr;
   public:
           string(char *s)
           {
                   ptr=new char[strlen(s)+1];
                   strcpy(ptr,s);
           }
           ~string()
           {
                   delete ptr;
           }
           void print()
           {
                   cout<<ptr<<endl;
           }
           string operator=(const string s )
           {
           if (this==&s) return *this;
           delete ptr;
           ptr=new char[strlen(s.ptr)+1];
           strcpy(ptr,s.ptr);
           return *this;
                }
   };
     void main()
   {
           string p1("chen";
           {
                   string p2("  ";
                   p2=p1;
                   cout<<"p2:"<<endl;
                   p2.print();
           }
           cout<<"p1:"<<endl;
           p1.print();
   }

论坛徽章:
0
2 [报告]
发表于 2004-11-03 20:02 |只看该作者

c++函数重载问题讨论!!

另外对于别的运算符重载是就不用加&,举例来说吧:
  1. #include <iostream.h>;
  2. class over
  3. {
  4.     int i1;
  5.     public:
  6.     over()
  7.     {
  8.         i1=12;
  9.     }
  10.     void get(int j)
  11.     {
  12.         i1=j;
  13.     }
  14.     over operator ++()
  15.     {
  16.         i1++;
  17.         return *this;
  18.     }
  19.     void print()
  20.     {
  21.         cout<<i1<<endl;
  22.     }
  23.    
  24. };
  25. void main()
  26. {
  27.     over o1,o2;
  28.     int j;
  29.     j=33;
  30.     o2.get(j);
  31.     o1.print();
  32.     o2.print();
  33.     o2++;
  34.     o1.print();
  35.     o2.print();
  36. }
复制代码

就可以正确执行,另外将over operator ++()改为over &operator ++()也是对的,为什么??

论坛徽章:
0
3 [报告]
发表于 2004-11-05 08:59 |只看该作者

c++函数重载问题讨论!!

这个应该在书上有讲到的。

“=”和“[]”这两个运算符,其返回值都必须是对对象的引用。因为他们的运算结果可能──而且必须保证可以──作为左值。比方说“+”重载,根本不会有
a+b=c;
这样的赋值语句出现,但是=呢?就有可能:
(a=b)++;

a[2]=b;
这样都是允许的。

一时讲不明白,看看书吧

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
4 [报告]
发表于 2004-11-05 12:48 |只看该作者

c++函数重载问题讨论!!

原帖由 "albcamus" 发表:
这个应该在书上有讲到的。

“=”和“[]”这两个运算符,其返回值都必须是对对象的引用。因为他们的运算结果可能──而且必须保证可以──作为左值。比方说“+”重载,根本不会有
a+b=c;
这样的赋值语句出现,但是=呢?就有可能:
(a=b)++;

a[2]=b;
这样都是允许的。
一时讲不明白,看看书吧
如果不清楚呢就不要讲得让别人以为是真的一样.在哪里看到说=,[]这两个运算符其返回值都必须是对象的引用?

楼主可以把你的编译器,环境写出来,编译错误帖出来,在我的dev-cpp4.9.9下没有问题,只是你的程序不是标准的程序给了两个警告,当然main的返回值我改掉了(这是一个错误)参数为引用还是值类型都不是问题.关键的关键应该是你的string和std::string可能出现重复(我不知道带.h的头文件形式那个C++ string类与C标准头文件string.h是怎么处理的,所以我不确定是否一定是这个问题,所以请给出编译错误).我不喜欢这种非标准的程序:
我改为如下:
  1. #include <iostream>;
  2. #include <cstring>;
  3. using std::cout;
  4. using std::endl;
  5. using std::strlen;
  6. using std::strcpy;
  7. using std::system;

  8. class string
  9. {
  10. char *ptr;
  11. public:
  12. string(char *s)
  13. {
  14. ptr=new char[strlen(s)+1];
  15. strcpy(ptr,s);
  16. }
  17. ~string()
  18. {
  19. delete ptr;
  20. }
  21. void print()
  22. {
  23. cout<<ptr<<endl;
  24. }
  25. string operator=(const string s )
  26. {
  27. if (this==&s) return *this;
  28. delete ptr;
  29. ptr=new char[strlen(s.ptr)+1];
  30. strcpy(ptr,s.ptr);
  31. return *this;
  32. }
  33. };
  34. int main()
  35. {
  36. string p1("chen");
  37. {
  38. string p2(" ");
  39. p2=p1;
  40. cout<<"p2:"<<endl;
  41. p2.print();
  42. }
  43. cout<<"p1:"<<endl;
  44. p1.print();

  45. system("PAUSE");
  46. }
复制代码

论坛徽章:
0
5 [报告]
发表于 2004-11-05 13:05 |只看该作者

c++函数重载问题讨论!!

原帖由 "THEBEST" 发表:

如果不清楚呢就不要讲得让别人以为是真的一样.在哪里看到说=,[]这两个运算符其返回值都必须是对象的引用?


可我的确是从书上这么看来的啊。看的是一本叫做《C++语言程序设计》的书,清华出版社,郑莉著,第二版,第九章《群体类》,第272页

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
6 [报告]
发表于 2004-11-05 13:10 |只看该作者

c++函数重载问题讨论!!

[quote]原帖由 "albcamus"]可我的确是从书上这么看来的啊。看的是一本叫做《C++语言程序设计》的书,清华出版社,郑莉著,第二版,第九章《群体类》,第272页[/quote 发表:
有没有电子版本的?
恐怕是你看错了吧?或者说他有前提,一般是这么写而不是说一定要这么写.

再说:你觉得我上面的程序如何?我不是照样用非传引用?不要全信书.

论坛徽章:
0
7 [报告]
发表于 2004-11-05 13:18 |只看该作者

c++函数重载问题讨论!!

书上这么说的:

如果一个函数的返回值是一个对象的值,它就被认为是一个常量,当然不能成为左值。对于+、-这样的运算符,我们将其运算结果作为常量失迎改的,因为绝不希望意外地改变这个结果。然而[]运算符就不同了,恰恰经常需要将它作为左值。实现这个愿望的办法就是,将[]重载函数的返回值指定为引用。由于引用的实质就是对象的地址,所以通过引用当然可以改变对象的值。

又说:

下面的语句:
int a,b=5;
(a=b)++;
这在C++中式允许的,运行之后a的值为6.这说明C++中要求赋值表达式是可以作为左值的。



我觉得这段话说的非常精彩。当然,倘若你的重载运算符所在的表达式(指的是赋值表达式或者使用下标随即访问的表达式)并没有在程序中作为左值出现,那么,在语法上也还是可以通过的;所以,所谓“必须返回引用”并不是语法上的强制,而是逻辑上的必须。

论坛徽章:
0
8 [报告]
发表于 2004-11-05 13:22 |只看该作者

c++函数重载问题讨论!!

恐怕是你看错了吧?或者说他有前提,一般是这么写而不是说一定要这么写.


厉害!那书上的的意思就是:“必须”是逻辑上的,不是语法上的。

老实说,楼主的代码我没有看,但看他说重载+可以而=不可以,又是引用的问题,自然就想到了这个。

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
9 [报告]
发表于 2004-11-05 13:30 |只看该作者

c++函数重载问题讨论!!

然而[]运算符就不同了,恰恰经常需要将它作为左值。实现这个愿望的办法就是,将[]重载函数的返回值指定为引用。
从你给出的话来看我没有发现书上讲的是错的而是你自己加上去的"一定".作者只是说了"实现这个愿望的办法是..."而非"一定"要这么做.也就是讲:

"在需要改变运算符重载返回值的时候你就一般得用引用,而在不需要改变时也可以用传值方式".如果我写一个类不允许你通过operator[]来改变返回值又如何呢?就像const A &operator[]()const;它不允许改变返回值,也就可以写成const A operator[]()const;只不过是前者效率更高而矣.

论坛徽章:
0
10 [报告]
发表于 2004-11-05 16:31 |只看该作者

c++函数重载问题讨论!!

我在VC6.0中编译了你的程序,错出在p2.print()。在你的类中加上有内存重新分配的拷贝构造函数试试。当退出operator=()之后,s被析构,即p2.ptr被删除了,其内容是不确定的。因此在调用p2.print()时出错。另外,正如楼上说的那样,你的类和标准string类有歧义。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP