- 头文件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++”所占用的内存就无法被正确用析构函数释放。