默认复制构造函数的浅探

  • 头文件stringbad1.h
     1 #include <iostream>
     2  #ifndef STRINGBAD_H_
     3  #define STRINGBAD_H_
     4  
     5  class StringBad{
     6  private:
     7      char * str;
     8      int len;
     9      static int num_strings;
    10  public:
    11      StringBad();
    12      StringBad(const char * s); 
    13      ~StringBad();
    14      //friend function
    15      friend std::ostream & operator<<(std::ostream & os, 
    16              const StringBad & s); 
    17  };
    18  
    19  #endif
  • 类定义stringbad1.cc
     1  #include "stringbad1.h"
     2  #include <cstring> // for strlen and strcpy
     3  using std::cout;
     4  
     5  int StringBad::num_strings = 0;
     6  
     7  StringBad::StringBad()
     8  {
     9      len = 4;
    10      str = new char[len];
    11      std::strcpy(str, "C++");
    12      num_strings++;
    13      //for your information
    14      cout << num_strings << ": "" << str <<  
    15          """ << "default object created.
    ";
    16  }
    17  
    18  //note:this is an bad idea to change "s"
    19  StringBad::StringBad(const char * s)
    20  {
    21      len = std::strlen(s);
    22      str = new char[len + 1]; 
    23      std::strcpy(str, s); 
    24      num_strings++;
    25      //FYI
    26      cout << num_strings << ": "" << str <<
    27           """ << "object created.
    ";
    28  }
    29  
    30  StringBad::~StringBad()
    31  {
    32      cout << """ << str << """ << "deleted."
    33     cout << """ << str << """ << "deleted."
    34           << --num_strings << " left.
    ";
    35      delete [] str;
    36  }
    37  
    38  std::ostream & operator<<(std::ostream & os,
    39          const StringBad & st)
    40  {
    41      os << st.str;
    42      return os;
    43  }
  • 函数usestring1.cc
     1  #include <iostream>
     2  #include "stringbad1.h"
     3  using std::cout;
     4  
     5  int main(void)
     6  {
     7      using std::endl;
     8      {   
     9          cout << "Starting an inner block.
    ";
    10          StringBad headline("The first string!");
    11          StringBad sports = "basketball";
    12          cout << "Sport: "    << sports   << endl;
    13          cout << "headline: " << headline << endl;
    14  
    15          cout << "Initialize one object to anther:
    ";
    16          StringBad sailor = sports;
    17          cout << "Sailor: "    << sailor    << endl;
    18          cout << "Sport2: "    << sports   << endl;
    19  
    20          cout << "Assign one object to anther: 
    ";
    21          StringBad knot;
    22          knot = headline;
    23          cout << "knot: "      << knot << endl;
    24          cout << "headline2: " << headline << endl;
    25  
    26          cout << "Exing the block.
    ";
    27      }   
    28      cout << "end of main().
    ";
    29  
    30      return 0;
    31  }
    32 /***************************************************
    33   * Starting an inner block.
    34   * 1: "The first string!"object created.
    35   * 2: "basketball"object created.
    36   * Sport: basketball
    37   * headline: The first string!
    38   * Initialize one object to anther:
    39   * Sailor: basketball
    40   * Sport2: basketball
    41   * Assign one object to anther: 
    42   * 3: "C++"default object created.
    43   * knot: The first string!
    44   * headline2: The first string!
    45   * Exing the block.
    46   * "The first string!"deleted.2 left.
    47   * "basketball"deleted.1 left.
    48   * " �8"deleted.0 left. 
    49   * * ***********************************************/

     通过程序输出。我们看到3: "C++"default object created. ,这一句其实时由于 StringBad knot; 而创建的。由此我们知道在声明对象时:调用默认构造函数。 这不是什么惊天动地的结论,但我们仔细想想,为什么会出现这句:" �8"deleted.0 left. 。这句是由于内存上的错误造成的,为什么会这样?看这句:knot = headline; 。这句将headline的值赋给knot,但knot本身的值是C++,也就是说knot是标识C++的唯一标记,但将headline赋值给knot时,knot也就必须要放弃对C++的标识而接受headline的内容。所以本来“C++”所占用的内存就无法被正确用析构函数释放。

原文地址:https://www.cnblogs.com/busui/p/5773643.html