1. #include <iostream> 
  2. using namespace std; 
  3. class Test { 
  4. public
  5.     // 构造函数 
  6.     Test() { 
  7.         i = new int(1); 
  8.     } 
  9.     // 析构函数 
  10.     ~Test() { 
  11.         // 释放i指向的内存 
  12.         delete i; 
  13.         i = 0; 
  14.     } 
  15.  
  16.     // 显示i的数值 
  17.     void show() { 
  18.         cout << *i << endl; 
  19.     } 
  20.  
  21. private
  22.     int * i; 
  23. }; 
  24.  
  25. // 将对象Test以拷贝的方式传递之后,由于变量t在函数作用域结束之后,会被注销。 
  26. // 因此会调用析构函数,也就是说指针i会被删除掉。 
  27. void test(Test t) { 
  28.     t.show(); 
  29.  
  30. int main() { 
  31.     Test t1; 
  32.     test(t1); 
  33.     // 此时t对象的show函数被调用的时候,t对象中的i已经是一个空指针了,因此程序会报错。 
  34.     t1.show(); 
  35.     return 0; 
这个时候需要使用复制构造函数来解决这个问题:
  1. #include <iostream> 
  2. using namespace std; 
  3. class Test { 
  4. public
  5.     // 构造函数 
  6.     Test() { 
  7.         i = new int(1); 
  8.     } 
  9.     // 复制构造函数 
  10.     Test(Test & t) { 
  11.         // 为拷贝的对象生成一个新的指针。 
  12.         i = new int(*t.i); 
  13.     } 
  14.     // 析构函数 
  15.     ~Test() { 
  16.         cout << 析构函数 << endl; 
  17.         // 释放i指向的内存 
  18.         delete i; 
  19.         i = 0; 
  20.     } 
  21.  
  22.     // 显示i的数值 
  23.     void show() { 
  24.         (*i)++; 
  25.         cout << *i << endl; 
  26.     } 
  27.  
  28. private
  29.     int * i; 
  30. }; 
  31.  
  32. // 当该函数执行完时,依然会调用析构函数。但是此时释放的是拷贝对象中的i的内存 
  33. // 并不影响main函数的i指针。 
  34. void test(Test t) { 
  35.     t.show(); 
  36.  
  37. int main() { 
  38.     Test t1; 
  39.     test(t1); 
  40.     // 此时t对象的show函数被调用的时候,t对象中的i没有受到影响,因此程序正常。 
  41.     t1.show(); 
  42.     return 0; 


输出:
2
析构函数
2
析构函数

可以发现,析构函数被调用了两次。这就是因为在test函数中的局部变量t,在函数执行完之后,被注销时触发了一次析构函数。
同时,我们要注意一个问题:明明在show()函数中调用了两次i++,但是为何输出是2跟2,而不是2跟3?
那是因为,当复制构造函数被触发时,test()函数中的对象t,与main函数中的t不是一个对象。