先来一段会出错的代码:
#pragma once #include <iostream> class StringBad { public: StringBad(const char *s); StringBad(); ~StringBad(); //friend friend std::ostream &operator <<(std::ostream &os, const StringBad &st); private: char *str; int len; static int num_strings; };
#include "StdAfx.h" #include "StringBad.h" 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++; std::cout << num_strings << ": \"" << str << "\"object created \n"; } StringBad::StringBad() { len = std::strlen("hello world"); str = new char[len + 1]; std::strcpy(str, "hello world"); num_strings++; std::cout << num_strings << ": \"" << str << "\"object created \n"; } StringBad::~StringBad() { std::cout << "\"" << str << "\" object delete, "; --num_strings; std::cout << num_strings << " left\n"; delete []str; } std::ostream & operator<<( std::ostream &os, const StringBad &st ) { os << st.str; return os; }
// TestObjectThink.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include "StringBad.h" using std::cout; using std::endl; void callMe1(StringBad &rsb) { cout << "reference" << endl; cout << "\"" << rsb << "\"" << endl; } void callMe2(StringBad rsb) { cout << "value" << endl; cout << "\"" << rsb << "\"" << endl; } int _tmain(int argc, _TCHAR* argv[]) { { cout << "Starting an inner block \n"; StringBad hello01("hello_01"); StringBad hello02("hello_02"); StringBad hello03("hello_03"); cout << "hello01: " << hello01 << endl; cout << "hello02: " << hello02 << endl; cout << "hello03: " << hello03 << endl; callMe1(hello01); cout << "hello01: " << hello01 << endl; callMe2(hello02); cout << "hello02: " << hello02 << endl; //等效于StringBad hello01Temp = StringBad(hello01); //新建一个对象并将其初始化为同类现有对象时,会调用复制构造函数。 StringBad hello01Temp = hello01; cout << "hello01Temp:" << hello01Temp << endl; StringBad hello03Temp; hello03Temp = hello03; cout << "hello03Temp:" << hello03Temp << endl; //system("pause"); } return 0; }
callMe2()调用完数据出错了,最后在对象释放时出现了崩溃性的错误,解决方法,加入下面两个函数。
StringBad::StringBad( const StringBad &st ) { num_strings++; len = st.len; str = new char[len + 1]; std::strcpy(str, st.str); std::cout << num_strings << ": \"" << str << "\"object created(copy) \n"; } StringBad & StringBad::operator=( const StringBad &st ) { if (this == &st) { return *this; } delete []str; len = st.len; str = new char[len + 1]; std::strcpy(str, st.str); std::cout << num_strings << ": \"" << str << "\"(assign) \n"; return *this; }
有空了再加上原因, 想急切了解的,参考:C++ primer plus(第六版) P425