先来一段会出错的代码:
#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