BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #42494同步于 2010/8/18
CPP机器人发帖

[合集] 拷贝构造函数和赋值函数

shenlei
2010/8/18镜像同步0 回复
☆─────────────────────────────────────☆ luweiyang (恋爱顾问) 于 (Sun Apr 26 21:06:38 2009) 提到: 在写一个循环队列的模板 期间遇到了很多构造函数方面的问题,在此向诸位请教一下 希望最后能来个总结 1 默认的拷贝构造函数与默认的赋值函数有什么相同点和不同点呢? 3 自己在写拷贝构造函数和赋值函数的时候又该注意什么问题呢? ☆─────────────────────────────────────☆ Jarod (学五608鬼魂) 于 (Sun Apr 26 21:12:31 2009) 提到: 这个自己总结多好。。。。请人写文章要BG的 ☆─────────────────────────────────────☆ luweiyang (恋爱顾问) 于 (Sun Apr 26 22:38:43 2009) 提到: 我自己有一些想法,只是不知道对错,再者想集思广益,然后总结一下,给大家看 这也要BG 难道与大家分享知识经验不是一件很快乐的事吗? 默认的拷贝函数和赋值函数的功能是一样的,实行位拷贝 在自己写这两个函数的时候,要特别注意指针,到底是拷贝指针,还是指针所指向的东西 【 在 Jarod 的大作中提到: 】 : 这个自己总结多好。。。。请人写文章要BG的 ☆─────────────────────────────────────☆ Jarod (3线操作失败男) 于 (Sun Apr 26 23:09:20 2009) 提到: 我说了,“写文章”........总结一两句话当然不需要BG啦。。。。 【 在 luweiyang 的大作中提到: 】 : 我自己有一些想法,只是不知道对错,再者想集思广益,然后总结一下,给大家看 : 这也要BG : 难道与大家分享知识经验不是一件很快乐的事吗? : ................... ☆─────────────────────────────────────☆ Vampire (吸血鬼) 于 (Mon Apr 27 00:10:19 2009) 提到: 我怎么觉得这个问题看C++ Primer和Effective C++之类的书就行了…… P.S. 楼主会布鲁斯口琴么?喜欢JJMilteau? ☆─────────────────────────────────────☆ gg66651525 (七鹅) 于 (Mon Apr 27 08:20:16 2009) 提到: 【 在 Jarod 的大作中提到: 】 : 我说了,“写文章”........总结一两句话当然不需要BG啦。。。。 2楼是来捣乱的~!~!愿意交流就说,不愿意不要说风凉话,~! ☆─────────────────────────────────────☆ DasheWan (忘情忘爱|有情有义) 于 (Mon Apr 27 08:51:43 2009) 提到: 1 默认的拷贝构造函数与默认的赋值函数有什么相同点和不同点呢? 拷贝构造函数使用在用已有对象创建新对象的时候的 赋值函数是创建完对象后,将另一个对象的值赋给它时调用的 如 new A(B);调用拷贝构造函数 new A; A=B;//调用赋值函数 3 自己在写拷贝构造函数和赋值函数的时候又该注意什么问题呢? 需要自己写的时候基本上是涉及到动态内存分配的时候, 应该注意内存的分配和回收吧。 ☆─────────────────────────────────────☆ luweiyang (恋爱顾问) 于 (Mon Apr 27 10:06:55 2009) 提到: 看来被鄙视了 吹过复音的,菜鸟级 后来觉得复音口琴太大了,买了个十孔的 不过吹得特别费力 JJMilteau,大牛阿! 【 在 Vampire 的大作中提到: 】 : 我怎么觉得这个问题看C++ Primer和Effective C++之类的书就行了…… : P.S. 楼主会布鲁斯口琴么?喜欢JJMilteau? ☆─────────────────────────────────────☆ luweiyang (恋爱顾问) 于 (Mon Apr 27 10:11:01 2009) 提到: 如果是 A a = b; 是否是先调用缺省构造函数,再调用赋值函数呢? 【 在 DasheWan 的大作中提到: 】 : 1 默认的拷贝构造函数与默认的赋值函数有什么相同点和不同点呢? : 拷贝构造函数使用在用已有对象创建新对象的时候的 : 赋值函数是创建完对象后,将另一个对象的值赋给它时调用的 : ................... ☆─────────────────────────────────────☆ Jarod (3线操作失败男) 于 (Mon Apr 27 10:35:02 2009) 提到: 一般是。。。copy ctor.... 先前的帖子有讨论过这问题。。。最后变成了与编译器实现相关的。。。 【 在 luweiyang 的大作中提到: 】 : 如果是 : A a = b; : 是否是先调用缺省构造函数,再调用赋值函数呢? ☆─────────────────────────────────────☆ tomxaoying (XiaoTOM) 于 (Mon Apr 27 11:25:24 2009) 提到: 相同点:对于深拷贝,都要分配内存,然后拷贝数据 不同点:如果是赋值函数,则要释放当前的内存,构造函数就不需要 注意的问题:写赋值函数在释放内存前,要注意避免自赋值的情况 啊以上是个人的一点理解 ☆─────────────────────────────────────☆ cymvp (cymvp) 于 (Mon Apr 27 11:54:16 2009) 提到: 这个应该不是和编译器相关的吧,应该是c++规定的吧 【 在 Jarod 的大作中提到: 】 : 一般是。。。copy ctor.... : 先前的帖子有讨论过这问题。。。最后变成了与编译器实现相关的。。。 ☆─────────────────────────────────────☆ Jarod (3线操作失败男) 于 (Mon Apr 27 12:36:04 2009) 提到: 因为那次讨论的最后提到了一些极端的例子。 【 在 cymvp 的大作中提到: 】 : 这个应该不是和编译器相关的吧,应该是c++规定的吧 ☆─────────────────────────────────────☆ cymvp (cymvp) 于 (Mon Apr 27 12:46:42 2009) 提到: 那次的讨论和这个不同,这个是c++标准规定的,请看iso c++(03版的)8.5: The initialization that occurs in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and brace-enclosed initializer lists (8.5.1) is called copy-initialization and is equivalent to the form T x = a; 【 在 Jarod 的大作中提到: 】 : 因为那次讨论的最后提到了一些极端的例子。 ☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Mon Apr 27 12:48:49 2009) 提到: 【 在 luweiyang 的大作中提到: 】 : 如果是 : A a = b; : 是否是先调用缺省构造函数,再调用赋值函数呢? 不是啊 这种就是和 A a(b); 一样的 ☆─────────────────────────────────────☆ Jarod (3线操作失败男) 于 (Mon Apr 27 12:57:29 2009) 提到: nod.....shit....我翻不到贴子了。。。记忆力也不行了。 【 在 cymvp 的大作中提到: 】 : 那次的讨论和这个不同,这个是c++标准规定的,请看iso c++(03版的)8.5: : : The initialization that occurs in argument passing, function return, throwing an exception (15.1), handling : ................... ☆─────────────────────────────────────☆ luweiyang (恋爱顾问) 于 (Mon Apr 27 13:35:55 2009) 提到: 我刚才google了下 说的和你一样 【 在 fox1987 的大作中提到: 】 : 不是啊 : 这种就是和 : A a(b); : ................... ☆─────────────────────────────────────☆ luweiyang (恋爱顾问) 于 (Mon Apr 27 13:50:18 2009) 提到: 我认为根本就没有浅拷贝,浅拷贝是深拷贝的另一种表现形式 就像程序设计语言中根本就没有传引用调用 要总结的话,也就是tomxaoying兄说的这些了 缺省拷贝构造函数和缺省赋值函数 相同点:分配内存,实行按位拷贝 不同点:赋值函数会释放当前内存,拷贝构造函数不会(拷贝构造函数调用之前,这个对象根本就不存在,何来释放内存) 写这两个函数时注意的问题:当对象中有指针时,一定要确定自己到底是要拷贝指针的值还是指针所指向的内存中的值; 另外赋值函数一定要避免自赋值。 再附上fox1987兄的信息: class A a; class A b = a; //该句调用的是拷贝构造函数,相当于 class A b(a); 【 在 tomxaoying 的大作中提到: 】 : 相同点:对于深拷贝,都要分配内存,然后拷贝数据 : 不同点:如果是赋值函数,则要释放当前的内存,构造函数就不需要 : 注意的问题:写赋值函数在释放内存前,要注意避免自赋值的情况 : ................... ☆─────────────────────────────────────☆ cymvp (cymvp) 于 (Mon Apr 27 14:09:22 2009) 提到: 大家都说得很不错啊,呵呵那给大家出个题一起看看: #include "stdio.h" class Thing { public: Thing(); Thing(const Thing&); }; Thing f() { Thing t; return t; } Thing::Thing() { printf("1"); } Thing::Thing(const Thing&) { printf("2"); } Thing t2 = f(); int main() { return 1; } 结果是什么? 【 在 luweiyang 的大作中提到: 】 : 我认为根本就没有浅拷贝,浅拷贝是深拷贝的另一种表现形式 : 就像程序设计语言中根本就没有传引用调用 : 要总结的话,也就是tomxaoying兄说的这些了 : ................... ☆─────────────────────────────────────☆ fox1987 (王子的狐狸§邪恶VS天真) 于 (Mon Apr 27 14:13:25 2009) 提到: 1 2? ☆─────────────────────────────────────☆ sunway (sunway) 于 (Mon Apr 27 14:28:52 2009) 提到: 编译器不会生成一个缺省的构造/赋值函数,而这个函数又仅仅用来作按位拷贝,这种额外的函数调用的开销没有必要. Default constructors and copy constructors…are generated (by the compiler) where needed. Needed in this instance means when the class does not exhibit bitwise copy semantics When are bitwise copy semantics not exhibited by a class? There are four instances: 1. When the class contains a member object of a class for which a copy constructor exists (either explicitly declared by the class designer, as in the case of the previous String class, or synthesized by the compiler, as in the case of class Word) 2. When the class is derived from a base class for which a copy constructor exists (again, either explicitly declared or synthesized) 3. When the class declares one or more virtual functions 4. When the class is derived from an inheritance chain in which one or more base classes are virtual 【 在 luweiyang (恋爱顾问) 的大作中提到: 】 : 标 题: Re: 拷贝构造函数和赋值函数 : 发信站: 北邮人论坛 (Mon Apr 27 13:50:18 2009), 站内 : : 我认为根本就没有浅拷贝,浅拷贝是深拷贝的另一种表现形式 : 就像程序设计语言中根本就没有传引用调用 : : 要总结的话,也就是tomxaoying兄说的这些了 : : 缺省拷贝构造函数和缺省赋值函数 : 相同点:分配内存,实行按位拷贝 : 不同点:赋值函数会释放当前内存,拷贝构造函数不会(拷贝构造函数调用之前,这个对象根本就不存在,何来释放内存) : 写这两个函数时注意的问题:当对象中有指针时,一定要确定自己到底是要拷贝指针的值还是指针所指向的内存中的值; : 另外赋值函数一定要避免自赋值。 : : 再附上fox1987兄的信息: : class A a; : class A b = a; //该句调用的是拷贝构造函数,相当于 class A b(a); : : : 【 在 tomxaoying 的大作中提到: 】 : : 相同点:对于深拷贝,都要分配内存,然后拷贝数据 : : 不同点:如果是赋值函数,则要释放当前的内存,构造函数就不需要 : : 注意的问题:写赋值函数在释放内存前,要注意避免自赋值的情况 : : ................... : : -- : : ※ 来源:·北邮人论坛 http://forum.byr.edu.cn·[FROM: 2001:da8:215:9904:21b:38ff:fea1:*] ☆─────────────────────────────────────☆ Vampire (吸血鬼) 于 (Mon Apr 27 15:23:29 2009) 提到: 没有鄙视啊~ 我只是觉得那两本书讲得比较清楚而已~ 有空交流交流口琴啊~ 【 在 luweiyang 的大作中提到: 】 : 看来被鄙视了 : 吹过复音的,菜鸟级 : 后来觉得复音口琴太大了,买了个十孔的 : ................... ☆─────────────────────────────────────☆ Vampire (吸血鬼) 于 (Mon Apr 27 15:24:09 2009) 提到: 12 是吧? 【 在 cymvp 的大作中提到: 】 : 大家都说得很不错啊,呵呵那给大家出个题一起看看: : #include "stdio.h" : class Thing { : ................... ☆─────────────────────────────────────☆ cymvp (cymvp) 于 (Mon Apr 27 15:27:55 2009) 提到: 可以试试不同的编译器,结果应该是不一样的,但是都是正确的。给答案的时候说说自己的思考过程 【 在 Vampire 的大作中提到: 】 : 12 : 是吧? ☆─────────────────────────────────────☆ xiaoNavy (风花雪月) 于 (Mon Apr 27 15:58:04 2009) 提到: 我用DEV--c++编译运行是 1 visual c++编译运行是1 2 2 【 在 cymvp 的大作中提到: 】 : 大家都说得很不错啊,呵呵那给大家出个题一起看看: : #include "stdio.h" : class Thing { : ................... [em9][em9][em9] ☆─────────────────────────────────────☆ Jarod (3线操作失败男) 于 (Mon Apr 27 16:01:21 2009) 提到: 我怎么觉得应该是nothing....算了........人脑作了过度优化了。。。 debug和release应该是不同结果,所以那些用gcc/cl的还需要考虑d/r两情况。。 ☆─────────────────────────────────────☆ windfantasy (野人帮之十三姨|永远的05414|又见计忆邮心) 于 (Mon Apr 27 16:41:40 2009) 提到: 有点晕~ ☆─────────────────────────────────────☆ luweiyang (恋爱顾问) 于 (Mon Apr 27 17:58:44 2009) 提到: 很久未吹 本属菜鸟 【 在 Vampire 的大作中提到: 】 : 没有鄙视啊~ : 我只是觉得那两本书讲得比较清楚而已~ : 有空交流交流口琴啊~ ☆─────────────────────────────────────☆ luweiyang (恋爱顾问) 于 (Mon Apr 27 18:15:01 2009) 提到: 我g++编译却 运行时无现象 全局数据定义时会初始化 不过这里是用一个函数给他赋值 在运行的时候因该是看到reurn 1 就退出了 不过在前面发生了什么事情我不甚明了 如果是问构造函数的话 应该是先调用缺省构造函数,然后调用拷贝构造函数 【 在 cymvp 的大作中提到: 】 : 可以试试不同的编译器,结果应该是不一样的,但是都是正确的。给答案的时候说说自己的思考过程 ☆─────────────────────────────────────☆ luweiyang (恋爱顾问) 于 (Mon Apr 27 18:30:53 2009) 提到: 对,并不是任何情况下编译起都会生成缺省构造函数和缺省拷贝函数 而是在需要的时候才会生成 class A { int a, b; A(int _a,int _b) { a = _a; b = _b;} }; A a1(1,2); A a2 (a1); 这种情况下编译器应该会生成缺省的拷贝构造函数,并且仅仅是用来按位拷贝 请问兄台说的“编译器不会生成一个缺省的构造/赋值函数,而这个函数又仅仅用来作按位拷贝,这种额外的函数调用的开销没有必要. “是什么意思? 关于那四点,等下再说 【 在 sunway 的大作中提到: 】 : 编译器不会生成一个缺省的构造/赋值函数,而这个函数又仅仅用来作按位拷贝,这种额外的函数调用的开销没有必要. : Default constructors and copy constructors…are generated (by the compiler) where needed. : Needed in this instance means when the class does not exhibit bitwise copy semantics : ................... ☆─────────────────────────────────────☆ sunway (sunway) 于 (Mon Apr 27 18:47:06 2009) 提到: 就是说编译器不会仅仅为了按位拷贝而生成一个缺省拷贝/赋值构造函数 (好像我原帖少了'拷贝'两个字..),而是在需要时直接按位拷贝而不是调用函数去按位拷贝 class Test { public: int a, b; Test(int _a,int _b) { a = _a; b = _b;} virtual void f () {} }; int main (int argc, char * argv[]) { Test a1(1,2); Test a2 (a1); return 0; } 在注释/不注释 virtual两种情况下,用 nm -a ./a.out|grep Test 可以看出来区别 【 在 luweiyang (恋爱顾问) 的大作中提到: 】 : 标 题: Re: 拷贝构造函数和赋值函数 : 发信站: 北邮人论坛 (Mon Apr 27 18:30:53 2009), 站内 : : 对,并不是任何情况下编译起都会生成缺省构造函数和缺省拷贝函数 : 而是在需要的时候才会生成 : : class A { : int a, b; : A(int _a,int _b) { a = _a; b = _b;} : }; : A a1(1,2); : A a2 (a1); : 这种情况下编译器应该会生成缺省的拷贝构造函数,并且仅仅是用来按位拷贝 : 请问兄台说的“编译器不会生成一个缺省的构造/赋值函数,而这个函数又仅仅用来作按位拷贝,这种额外的函数调用的开销没有必要. “是什么意思? : : 关于那四点,等下再说 : 【 在 sunway 的大作中提到: 】 : : 编译器不会生成一个缺省的构造/赋值函数,而这个函数又仅仅用来作按位拷贝,这种额外的函数调用的开销没有必要. : : Default constructors and copy constructors…are generated (by the compiler) where needed. : : Needed in this instance means when the class does not exhibit bitwise copy semantics : : ................... : : -- : : ※ 来源:·北邮人论坛 http://forum.byr.edu.cn·[FROM: 2001:da8:215:9904:21b:38ff:fea1:*] ☆─────────────────────────────────────☆ cymvp (cymvp) 于 (Mon Apr 27 20:06:33 2009) 提到: 编译器这么做不会对我们程序员有任何影响,因为编译器这么做不会有任何的副作用,主要是因为调用构造函数会带来函数压栈引起的效率问题,所以编译器的实现是能不调用尽量就不调用了。 【 在 sunway 的大作中提到: 】 : 就是说编译器不会仅仅为了按位拷贝而生成一个缺省拷贝/赋值构造函数 (好像我原帖少了'拷贝'两个字..),而是在需要时直接按位拷贝而不是调用函数去按位拷贝 : class Test { : public: : ...................
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。