一个C++的有意思的例子
最近为了学习QT,重新学习C++,拿起了厚厚的《C++ Primer Plus(第6版)》
第12章:类与动态内存分配
Stringbad.h
#pragma once #include <iostream> class Stringbad { private: char* str; int len; static int num_strings; public: Stringbad(const char* s); Stringbad(); ~Stringbad(); friend std::ostream& operator<<(std::ostream& os, const Stringbad& st); //Stringbad& operator=(const Stringbad& st); //Stringbad(const Stringbad& st); };
strngbad.cpp
#include "strngbad.h" #include <cstring> using std::cout; int Stringbad::num_strings = 0; Stringbad::Stringbad(const char* s) { len = std::strlen(s); str = new char[len + 1]; std::strcpy(str, s); num_strings++; cout << num_strings << ":\"" << str << "\" object created\n"; } Stringbad::Stringbad() { len = 4; str = new char[4]; std::strcpy(str, "C++"); num_strings++; cout << num_strings << ":\"" << str << "\" default object created\n"; } Stringbad::~Stringbad() { cout << "\"" << str << "\" object deleted,"; --num_strings; cout << num_strings << " left\n"; delete[] str; } std::ostream& operator<<(std::ostream& os, const Stringbad& st) { os << st.str; return os; } /* Stringbad& Stringbad::operator=(const Stringbad& st) { cout << "object assign " << st.str << std::endl; if (this == &st) return *this; delete[] str; len = st.len; str = new char(len + 1); std::strcpy(str, st.str); return *this; } Stringbad::Stringbad(const Stringbad& st) { len = st.len; str = new char[len + 1]; std::strcpy(str, st.str); num_strings++; cout << num_strings << ":\"" << str << "\" object copy.\n"; } */
看似没有问题的类定义,如下测试
#include <iostream> #include <string> #include "Stock.h" #include "strngbad.h" void callme1(Stringbad&); void callme2(Stringbad); int stonetolb(int st) { return 14 * st; } using std::cout; int main() { using std::endl; { cout << "String an inner block.\n"; Stringbad headline1("Celera Stalks at Midnight"); Stringbad headline2("Lettuce Prey"); Stringbad sports("Spinach Leaves Bowl for Dollars"); cout << "headline1:" << headline1 << endl; cout << "headline2:" << headline2 << endl; cout << "sports:" << sports << endl; callme1(headline1); cout << "headline1:" << headline1 << endl; callme2(headline2); cout << "headline2:" << headline2 << endl; cout << "Initialize one object to another:\n"; Stringbad knot; knot = headline1; cout << "knot: " << knot << endl; cout << "Exiting the block.\n"; } cout << "End of main()\n"; return 0; } void callme1(Stringbad& rsb) { cout << "String passed by reference:\n"; cout << " \"" << rsb << "\"\n"; } void callme2(Stringbad rsb) { cout << "String passed by reference:\n"; cout << " \"" << rsb << "\"\n"; }
结果,又是负数,又是乱码。以下是我的vs.net2019的运行结果,因为是异常退出,且输出的结果有时会少了一行,所以以下截图看不到-1的结果
上面的代码你会发现我注释了部分代码,恢复后,你会发现程序死得更早。因为在赋值函数如此创建的数组
str = new char(len + 1);
而如此delete
delete [] str;