拷贝构造函数和赋值运算符

isml 2006-08-15 09:47:59
由于这两个函数比较相似,所以似乎可以通过其中的某一个实现另一个
1、用赋值运算符实现拷贝构造函数(拷贝构造函数已定义)
A::A(const A & src)
{
*this = src;
}

有无副作用?

2、用拷贝构造函数实现赋值运算符(赋值运算符函数已定义)
这个似乎稍微麻烦点:
A & A::operator = (const A & src)
{
A temp(src);
swap(temp); /// 交换成员
return *this;
}

有无副作用?
...全文
322 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
isml 2006-08-16
  • 打赏
  • 举报
回复
要初始化基类成员就写在初始化列表中,自身成员不写在初始化列表中,而在函数体内用赋值运算符,我想这样应该可以的吧。
sinall 2006-08-16
  • 打赏
  • 举报
回复
这样效率是可以增加。不过效率和结构总是有矛盾的。
————————————————————————
请问,基类没有默认构造函数怎么办吧?
isml 2006-08-16
  • 打赏
  • 举报
回复
多谢解答。
效率方面我自己是清楚的,因为我也不止一遍看过Effective C++.只是对于第二个,就是用拷贝构造函数来定义赋值运算符,似乎在<<Applied C++>>中是推荐的。我也看了半天没明白,因为代码似乎只有增加没减少,但他的解释是这样定义赋值运算符函数要更安全的,并且说可以参见([Sutter00]),可能这是在两楼的朋友说的<<Exceptional C++>>中,因为我没看过这本书,所以不是很清楚。
genius_hb 2006-08-16
  • 打赏
  • 举报
回复
语言上是没有规定的。但这样做肯定不好。不然标准和必需要这几个不同的函数,effective c++为什么要提醒大家注意这几个函数的区别。。

对于第一个:
如果你有必要写operator =的话,说明对象中应该是和指针有关,或者资源的管理有关。那么在operator =中一般会先释放自己的资源,然后复制或得到=号另一端对象的资源。而构造函数中,首先分配了默认的资源,然后调用operator =销毁该资源,然后重新分配资源。这些重复工作的带来了不必要的开销吧

第二个也是多此一举
你平白无故的增加了一个临时对象的构造和析构的开销。你如何实现你的swap函数??其功能和正确的operator =有什么区别???
你其实是写了一个不是名为operator = 的函数swap,但其功能和operator = 一样。
isml 2006-08-16
  • 打赏
  • 举报
回复
这样效率是可以增加。不过效率和结构总是有矛盾的。
isml 2006-08-16
  • 打赏
  • 举报
回复
你是指直接在初始化列表中初始化自身吗?
sinall 2006-08-16
  • 打赏
  • 举报
回复
"拷贝构造,也是构造,如果用赋值函数实现,就不能使用初始化列表了!"
拷贝构造就是复制对象吧,所以初始化列表应该没有什么意义
——————————————————————————————————
无语了……,回去看看书再来吧。
isml 2006-08-16
  • 打赏
  • 举报
回复
"*this = src;这里一句不是太对的,因为src是类的对象,是不可以直接这样赋值的,除非你重载了赋值运算符。"

就是因为已经重载了赋值运算符,所以用它去实现拷贝构造.



"拷贝构造,也是构造,如果用赋值函数实现,就不能使用初始化列表了!"
拷贝构造就是复制对象吧,所以初始化列表应该没有什么意义



sinall 2006-08-16
  • 打赏
  • 举报
回复
1)拷贝构造,也是构造,如果用赋值函数实现,就不能使用初始化列表了!
2)swap为何物???你不得又要写一个swap,何苦?
rollor_phoe 2006-08-16
  • 打赏
  • 举报
回复
*this = src;这里一句不是太对的,因为src是类的对象,是不可以直接这样赋值的,除非你重载了赋值运算符。
isml 2006-08-15
  • 打赏
  • 举报
回复
多谢指点。
不过我对你说的“用赋值运算符实现拷贝构造函数明显是错的!”不是很理解。赋值运算符函数也分配资源的啊?能不能讲得具体些?
AdenPlus 2006-08-15
  • 打赏
  • 举报
回复
第一种方法 “用赋值运算符实现拷贝构造函数”明显是错的! 因为有很多资源需要在拷贝构造函数中创建,赋值构造函数中做的话就不对了!
AdenPlus 2006-08-15
  • 打赏
  • 举报
回复
我认为只有一种是对的,就是用拷贝构造函数实现赋值运算符!

在赋值构造函数中可以调用拷贝构造函数来实现,因为使用std::swap()不会抛出异常,所以更安全!详细的看<Exceptional C++>!
AdenPlus 2006-08-15
  • 打赏
  • 举报
回复
楼主是不是搞反了!

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧