您的位置:首页 > 编程语言 > C语言/C++

C++ Primer Plus(StringBad类的实现)

2016-11-02 11:43 204 查看
参考《C++Primer Plus 6th 类和动态内存分配》

首先实现一个功能有缺陷的StringBad类。

//stringbad.h
#include<iostream>
#ifndef STRINGBAD_H
#define STRINGBAD_H

class StringBad
{
private:
char * str;
int len;
static int num_strings;//无论创建多少个StringBad对象,程序之创建一个静态类变量副本
//这样可以方便地说明数据成员属性,比如用来记录所创建对象的数目
public:
StringBad(const char * s);
StringBad(const StringBad & st);
StringBad();
~StringBad();
StringBad & StringBad::operator=(const StringBad & st);
friend std::ostream & operator<<(std::ostream & os, const StringBad & st);
};
#endif


#include"stdafx.h"
#include<cstring>
#include"stringbad.h"
using std::cout;

int StringBad::num_strings = 0;
//静态数据成员在类声明中声明,在包含类方法的文件中初始化,初始化时使用作用域运算符来
//指出静态成员所属的类,但如果静态成员是const整数类型或者是枚举类型,则可以在声明中初始化

StringBad::StringBad(const StringBad & st)
{
num_strings++;
len = st.len;
str = new char[len + 1];
std::strcpy(str, st.str);
cout << num_strings << ": \"" << str <<"\" object created!\n\n";
}
StringBad::StringBad(const char * s)
{
len = std::strlen(s);
//strlen()返回字符串长度,但是并不包含末尾的空字符,因此分配内存长度为len+1
str = new char[len + 1];
std::strcpy(str, s);
num_strings++;
cout << "num_strings " << num_strings << ": " << str << "created!\n\n";

}

StringBad::StringBad()
{
len = 4;
str = new char[4];
std::strcpy(str, "C++");
num_strings++;
cout << num_strings << " : " << str << "default object created!\n\n";
}

StringBad::~StringBad()
{
cout << "\"" << str << "\" object deleted,";
--num_strings;
cout << num_strings << " left\n\n";
delete [] str;
}

std::ostream & operator<<(std::ostream & os, const StringBad &st)
{
os << st.str;
return os;
}

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);
return *this;
}


// StringBad.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
using std::cout;

#include"stringbad.h"

void callme1(StringBad &);
void callme2(StringBad);

int main()
{
using std::endl;
{
cout << "Starting an inner block.\n";
StringBad headline1("Celery Stalks at Midnight");
StringBad headline2("Lecttuce Prey");
StringBad sports("Spinach Leaves Bow1 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\n";
StringBad sailor = sports;//相当于运行了StringBad sailor = StringBad(sports);
//在这里,编译器会自动调用复制构造函数StringBad(const StringBad &),从而使得
//结果运行异常,结绝的方法是定义复制构造函数StringBad(const StringBad &)

cout << "sailor: " << sailor << endl;
cout << "Assign one object to another:\n\n";
StringBad knot;
knot = headline1;
cout << "knot: " << knot << endl;
cout << "Exiting the block.\n\n";
return 0;
}

cout << "End of main() \n\n";
}

void callme1(StringBad & rsb)
{
cout << "String passed by reference:\n\n";
cout << "     \"" << rsb << "\"\n\n";
}

void callme2(StringBad sb)
{
cout << "String passed by value: \n\n";
cout << "      \"" << sb << "\"\n\n";
}


在没有定义StringBad & StringBad::operator=(const StringBad & st)和StringBad(const StringBad & st)之前程序运行错误,VS2015弹出错误消息窗口,原因都是因为浅复制使得两个对象指向同一块内存空间,当编译器会调用默认构造函数,从而自动调用析构函数,然而多调用的析构函数作用到已经delete的内存空间,使得程序异常,显式定义默认复制构造函数和默认默认赋值运算符后程序正常。细节的问题书里有很详细的描述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: