关闭

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

发表于:2012-3-21 10:05

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试网采编

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

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

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

cstring str = strother;

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

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. if(m_pszbuffer != null)  
  54. {  
  55. free(m_pszbuffer);  
  56. m_pszbuffer = null;  
  57. }  
  58. m_pszbuffer = other.m_pszbuffer != null ? strdup(other.m_pszbuffer) : null;  
  59. return *this;  
  60. }  
  61. void test(cstring str)  
  62. {  
  63. cstring str1 = str;  
  64. return;  
  65. }  
  66. int main(int argc, char* argv[])  
  67. {  
  68. cstring str;  
  69. cstring str1 = "test";  
  70. cstring str2 = str1;  
  71. str1 = str;  
  72. cstring str3 = str3;  
  73. test(str);  
  74. return 0;  
  75. }

  希望对你有帮助。

《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号