浅谈C++对象的拷贝与赋值操作

开发 后端
本文介绍的是C++对象的拷贝与赋值操作,希望对大家有帮助,一起来看。

我发现一些同事在用C++编写一个类时,知道什么时候需要实现拷贝构造函数赋值操作,但不知道什么时候拷贝构造函数被调用,什么时候赋值操作被调用,甚至把二者混为一谈。

要弄明白这个问题,最简单的做法莫过于写个测试程序试一下。不过那样做也未必是好办法,实验的结果往往导致以偏概全的结论。不如好好想一下,弄清楚其中的原理,再去写程序去验证也不迟。

拷贝构造函数,顾名思义,等于拷贝 + 构造。它肩负着创建新对象的任务,同时还要负责把另外一个对象拷贝过来。比如下面的情况就调用拷贝构造函数:

  1. cstring str = strother; 

赋值操作则只含有拷贝的意思,也就是说对象必须已经存在。比如下面的情况会调用赋值操作。

  1. str = strother; 

不过有的对象是隐式的,由编译器产生的代码创建,比如函数以传值的方式传递一个对象时。由于看不见相关代码,所以不太容易明白。不过我们稍微思考一下,就会想到,既然是根据一个存在的对象拷贝生成新的对象,自然是调用拷贝构造函数了。

两者实现时有什么差别呢?我想有人会说,没有差别。呵,如果没有差别,那么只要实现其中一个就行了,何必要两者都实现呢?不绕圈子了,它们的差别是:

拷贝构造函数对同一个对象来说只会调用一次,而且是在对象构造时调用。此时对象本身还没有构造,无需要去释放自己的一些资源。而赋值操作可能会调用多次,你在拷贝之前要释放自己的一些资源,否则会造成资源泄露。

明白了这些道理之后,我们不防写个测试程序来验证一下我们的想法:

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. class cstring  
  5. {   
  6. public:  
  7. cstring();  
  8. cstring(const char* pszbuffer);  
  9. ~cstring();  
  10. cstring(const cstring& other);  
  11. const cstring& operator=(const cstring& other);  
  12. private:  
  13. char* m_pszbuffer;;  
  14. };   
  15. cstring::cstring()  
  16. {  
  17. printf("cstring::cstring\n");  
  18. m_pszbuffer = null;  
  19. return;   
  20. }   
  21. cstring::cstring(const char* pszbuffer)  
  22. {  
  23. printf("cstring::cstring(const char* pszbuffer)\n");  
  24. m_pszbuffer = pszbuffer != null ? strdup(pszbuffer) : null;  
  25. return;  
  26. }  
  27. cstring::~cstring()  
  28. {  
  29. printf("%s\n", __func__);  
  30. if(m_pszbuffer != null)  
  31. {  
  32. free(m_pszbuffer);  
  33. m_pszbuffer = null;  
  34. }  
  35. return;  
  36. }  
  37. cstring::cstring(const cstring& other)  
  38. {  
  39. if(this == &other)  
  40. {  
  41. return;  
  42. }  
  43. printf("cstring::cstring(const cstring& other)\n");  
  44. m_pszbuffer = other.m_pszbuffer != null ? strdup(other.m_pszbuffer) : null;  
  45. }  
  46. const cstring& cstring::operator=(const cstring& other)  
  47. {  
  48. printf("const cstring& cstring::operator=(const cstring& other)\n");  
  49. if(this == &other)  
  50. {  
  51. return *this;  
  52. }  
  53.  
  54. if(m_pszbuffer != null)  
  55. {  
  56. free(m_pszbuffer);  
  57. m_pszbuffer = null;  
  58. }  
  59. m_pszbuffer = other.m_pszbuffer != null ? strdup(other.m_pszbuffer) : null;  
  60. return *this;  
  61. }  
  62.  
  63. void test(cstring str)  
  64. {  
  65. cstring str1 = str;  
  66. return;  
  67. }  
  68.  
  69. int main(int argc, char* argv[])  
  70. {  
  71. cstring str;  
  72. cstring str1 = "test";  
  73. cstring str2 = str1;  
  74. str1 = str;  
  75. cstring str3 = str3;  
  76. test(str);  
  77. return 0;  

希望对你有帮助。

【编辑推荐】

  1. C++中static的用法总结
  2. C++内存管理的探讨
  3. C++的输出格式控制技巧分析
  4. C++多态技术的实现和反思
  5. C++中的指针用法汇集
责任编辑:于铁 来源: 互联网
相关推荐

2011-07-20 13:40:09

拷贝构造函数

2009-07-20 09:53:43

Java混合编程

2022-09-30 15:03:09

C语言深拷贝浅拷贝

2009-12-22 01:54:50

C++之父Bjarne Stro

2011-07-20 17:23:29

C++持久对象

2009-09-02 15:41:21

C# HTTPWebR

2009-08-12 11:24:25

C# String对象

2009-08-19 17:12:18

C# Connecti

2009-08-31 09:37:09

C# Employee

2012-09-18 13:26:39

CC++

2010-02-02 15:59:32

C++赋值函数

2024-01-03 13:38:00

C++面向对象编程OOP

2009-09-04 17:34:11

C#CC++

2010-02-06 17:09:29

C++文件拷贝

2011-04-08 09:52:44

C++C#DLL

2009-09-02 17:07:06

C#数组操作

2009-08-18 09:06:41

C#对象和集合

2009-09-02 16:36:37

C#调用Excel对象

2009-05-08 09:46:37

微软C#集合对象

2016-10-20 16:07:11

C++Modern C++异步
点赞
收藏

51CTO技术栈公众号