免费注册 查看新帖 |

Chinaunix

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

[函数] 构造函数、析构函数、对象传递? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-03-14 20:35 |只看该作者 |倒序浏览
1、在类应用中,当一个对像被作为参数传递时,它创建了对像的副本,如果没有声明复制构造函数时,默认的复制构造函数将按位复制的形式创建一个副本。
------------这个“按位复制”到底是怎么一回事?
2、传递对像时还有一个问题是,如果在用作实际参数的对象中分配了动态内存,那么它的副本在析构时会将原来的实际对像破坏掉。
比如:
class myclss{
int *p;
public:
myclass(int i);
~myclass();
int getval(){return *p;}
};
//构造函数
myclass::myclass(int i)
{
cout<<"Allocating p\n";
p=new int;
*p=i;
}
//析构函数
myclass::~myclass{
cout<<"Freeing p\n";
delete p;
}
//对像的传递函数
void display(myclass ob){
cout<<ob.getval()<<'\n';
}
//应用
int main(){
myclass a=10;
display(a);
return 0;
}

--上面中会对p析构两次
问:这里为什么动态分配时对对像的传递时,对像和原型指向同一个地址?
而那种普通的分配(在栈中分配的)时对对像的传递指向是不同地址?(这和按位复制形式有关吗?)

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2004-03-14 21:06 |只看该作者

构造函数、析构函数、对象传递?

建议看《effective c++》。
讲的很详细。

论坛徽章:
0
3 [报告]
发表于 2004-03-15 08:21 |只看该作者

构造函数、析构函数、对象传递?

指向同一个地址,连续2次的delete

论坛徽章:
0
4 [报告]
发表于 2004-03-15 20:59 |只看该作者

构造函数、析构函数、对象传递?

为什么是两次delete啊?不就是主函数结束时调用了一次析构函数吗?难道
display函数结束的时候还要析构吗?
那这个主函数该怎么写才能正确运行呢?

论坛徽章:
0
5 [报告]
发表于 2004-03-15 22:17 |只看该作者

构造函数、析构函数、对象传递?

拷贝构造函数分为深拷贝和浅拷贝两种,编译器给你提供的缺省的拷贝构造函数就是浅拷贝,也就是所说的位拷贝,因为编译器不知道如何处理你对象中的各个成员,因此就简单的创建了一个对象,然后将被拷贝的对象用memcpy()的方式拷贝到新对象。如果一个对象包含指针成员,那么这时侯两个对象指向的是同一个地方,每个对象在析构的时侯都要调用一次内存释放函数,是不是一个地方要删除两次呢。另外传给display的对象参数是在栈中构造的当然要调用拷贝构造函数,而且在函数退出的时侯,退栈操作也会调用栈中对象的构造函数。

论坛徽章:
0
6 [报告]
发表于 2004-03-16 08:27 |只看该作者

构造函数、析构函数、对象传递?

编译器提供的缺省的拷贝构造函数是“按位拷贝”,如果缺省的拷贝构造函数不能满足你的要求,你可以自己定义一个拷贝构造函数并且重载"="运算符。如果你在构造函数中申请了动态空间,那么你必须十分小心地使用它,并且要定义析构函数及时地回收空间,如果你从该类派生其他类,要将析构函数定义为virtual。

论坛徽章:
0
7 [报告]
发表于 2004-03-16 14:58 |只看该作者

构造函数、析构函数、对象传递?

原帖由 "逆水的游鱼" 发表:

那这个主函数该怎么写才能正确运行呢?

不是 main 函数中的问题,而是类成员函数的实现存在问题。要使这个程序正确,有两种修改方法:

1. 权宜之计
对于这个题目而言,适当修改 display 成员函数就能够使程序正确。把这个函数的参数传递方式由“值传递”改为“引用传递”就能解决问题,即把类中的 display 函数的定义修改为:void display(myclass& ob),函数体不变。还可以用指向对象的指针的方式:void display(myclass* pob),函数体作相应的变动。

2. 治本之法
正如上面 stevens_wu  所说的,要真正解决问题,还要定义自己的拷贝构造函数。我写了一个拷贝构造函数,供作测试用。
  1. myclass::myclass(myclass& obj)
  2. {
  3.     cout<<"Allocating (from object) = " << endl;
  4.     p=new int;
  5.     *p=*obj.p;
  6. }  
复制代码

类中有这样定义的拷贝构造函数之后,即使是调用 void display(myclass ob) 这样定义的函数以及 myclass a(10); myclass b(a); 这样用对象 a 对 b 进行初始化也没有问题了。

如果想通过赋值使用,如:a = b; 还要定义自己的“operator=”,不能使用缺省提供的。

还有,如果把类的 myclass(int i); 这个构造函数定义成 myclass(int i = 0) 这种形式,这个类的使用就更加方便了,它使程序中能够接受 myclass a; 这样的定义方式,而不仅仅是 myclass a(0)这种必须提供参数的方式,尽管它们定义的是同样的对象 a。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP