设为首页收藏本站

新微赢技术网

 找回密码
 注册
搜索
热搜: 回贴
查看: 1836|回复: 9
打印 上一主题 下一主题

一个传递对象的疑惑

[复制链接]
跳转到指定楼层
1#
发表于 2009-11-3 02:18:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下面这个程序是对象传递,它存在着潜在的问题应该在参数里使用引用,我不太清楚ob被销毁时,调用析构函数清除它所指向的内存,那它怎么还会被对象a使用???使用引用的话,就不必清除ob了吗??

#include<iostream>
#include<cstdlib>
using namespace std;
class myclass{
int *p;
public:
myclass(int i);
~myclass();
int getval(){
return *p;};
myclass::myclass(int i){
cout<<"allocating";
p=new int;
*p=i;}
myclass::~myclass(){
cout<<"freeing";
delete p;
}
void display(myclass ob)
{cout<<ob.getval()<<'\n';
}
int main(){
myclass a(10);
display(a);
return 0;
}
2#
发表于 2009-11-3 02:18:27 | 只看该作者
你应该知道,当自定义的类型做为参数按值传递给函数时,就一定会调用拷贝构造函数这件事情吧?
如果你已经知道了,那好:
拷贝构造函数的效果我举个例子:
class A{int x;char *p;} class B{int y;char *fp;}
这里A就相当于是实参,B就相当于是形参;
那么系统默认拷贝函数(因为你没有自己显示的定义一个拷贝构造函数)开始执行;
B.y=A.x; B.fp=A.p;
注意第2个语句;2个指针指向一个地址!
所以当形参(局部变量)结束生命周期时,会释放内存.那作为实际参数的A的对象指针将迷路(迷途指针,随意指向一个内存);
当A的对象结束生命周期,这个对象的析构函数被调用,释放那个指针指向的未知的地方(非常危险).
引用传递:
相当于直接把A作为形式参数;这样就不用调用拷贝构造函数了.
回复 支持 反对

使用道具 举报

3#
发表于 2009-11-3 02:18:28 | 只看该作者
如果不用引用
ob只是一个临时的对象
它与a没有任何关系
只是他们的值相等
display(a);
这里只用到它的值
如果用引用
那么ob与 a 直接相关(是一个东西)
delete其中一个的话,就是全部
回复 支持 反对

使用道具 举报

4#
发表于 2009-11-3 02:18:29 | 只看该作者

对不起
楼主
没看见你的new
这样的话,和wfpb一样
做一个拷贝吧,你用new了
回复 支持 反对

使用道具 举报

5#
发表于 2009-11-3 02:18:30 | 只看该作者
那是不是对象作为参数在不使用动态存储时最好是使用引用呢?对象作为参数传递的时候只能调用复制构造函数吗?
如果局部对象使用动态内存的话在对象,可不可以这样理解:
(1)如果对象传递对象的话会存在潜在问题
(2)如果引用传递的话局部对象,撤销时会造成实参内存丢失
(3)复制构造函数使局部变量和 实参不使用一个内存,失去局部变量也不会影响实参。
回复 支持 反对

使用道具 举报

6#
发表于 2009-11-3 02:18:32 | 只看该作者
  1. #include<iostream>
  2. #include<cstdlib>
  3. using namespace std;

  4. class myclass
  5. {
  6. int * p; //由于需要动态开辟空间,一定要小心,
  7. // 你为此需要 copy constructor 和 assignment operator
  8. public:
  9. myclass(int i);
  10. myclass(const myclass & object);
  11. myclass & operator=(const myclass & object);
  12. ~myclass();
  13. int getval()
  14. {
  15. return *p;
  16. }
  17. };

  18. myclass::myclass(int i)
  19. {
  20. cout<<"allocating";
  21. p=new int;
  22. *p=i;
  23. }

  24. myclass::myclass(const myclass & object)
  25. {
  26. p = new int;
  27. *p = *(object.p);
  28. }

  29. myclass & myclass::operator =(const myclass & object)
  30. {
  31. if(this == &object)
  32. return *this;
  33. delete p;
  34. p = new int;
  35. *p = *(object.p);
  36. return *this;
  37. }
  38. myclass::~myclass()
  39. {
  40. cout<<"freeing";
  41. if(p)
  42. delete p;
  43. }

  44. void display(myclass ob) // 如果你会单步调试的话,你再试试 (myclass & ob)
  45. {
  46. cout<<ob.getval()<<'\n';
  47. }

  48. int main()
  49. {
  50. myclass a(10);
  51. display(a);

  52. system("pause");
  53. return 0;
  54. }

复制代码
回复 支持 反对

使用道具 举报

7#
发表于 2009-11-3 02:18:33 | 只看该作者
myclass & myclass::operator =(const myclass & object)
{
if(this == &object)
return *this;
delete p;
p = new int;
*p = *(object.p);
return *this;
}

请问一下,为什么要重新给p分配空间?为什么要调用运算符的重载呢?我现在有些搞不清楚在程序里什么时候应该有运算符的重载出现??辛苦了!!谢谢
回复 支持 反对

使用道具 举报

8#
发表于 2009-11-3 02:18:34 | 只看该作者
kai:
在你的version中,是不是用引用传递效率更高一些,这样就无需作出实参的一个副本了。
回复 支持 反对

使用道具 举报

9#
发表于 2009-11-3 02:18:35 | 只看该作者
chenchao,
是的。
回复 支持 反对

使用道具 举报

10#
发表于 2009-11-3 02:18:37 | 只看该作者
以下是引用chenchao在2006-5-22 21:09:00的发言:
kai:
在你的version中,是不是用引用传递效率更高一些,这样就无需作出实参的一个副本了。
但别滥用,有修改原数据的危险,有时局部变量也很好
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

申请友链|小黑屋|最新主题|手机版|新微赢技术网 ( 苏ICP备08020429号 )  

GMT+8, 2024-11-18 07:34 , Processed in 0.131660 second(s), 10 queries , Gzip On, Memcache On.

Powered by xuexi

© 2001-2013 HaiAn.Com.Cn Inc. 寰耽

快速回复 返回顶部 返回列表