C++ Primer Plus(StringBad类的实现)
2016-11-02 11:43
204 查看
参考《C++Primer Plus 6th 类和动态内存分配》
首先实现一个功能有缺陷的StringBad类。
在没有定义StringBad & StringBad::operator=(const StringBad & st)和StringBad(const StringBad & st)之前程序运行错误,VS2015弹出错误消息窗口,原因都是因为浅复制使得两个对象指向同一块内存空间,当编译器会调用默认构造函数,从而自动调用析构函数,然而多调用的析构函数作用到已经delete的内存空间,使得程序异常,显式定义默认复制构造函数和默认默认赋值运算符后程序正常。细节的问题书里有很详细的描述。
首先实现一个功能有缺陷的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的内存空间,使得程序异常,显式定义默认复制构造函数和默认默认赋值运算符后程序正常。细节的问题书里有很详细的描述。
相关文章推荐
- C++ Primer Plus(StringBad类的改进)
- 读书笔记-C++PrimerPlus-8.2.6 对象、继承和引用10.2.5 修改实现
- C++ Primer Plus 札记(一) 数组,字符串和string
- C++ Primer Plus的string类的简单实现
- C++ Primer Plus(第五版)第五章编程练习题6(关于string难点哦)
- MyString类的实现--C++ primer plus 读书笔记
- C++实现CString和string的互相转换
- [c++ primer plus]main()执行之前
- (摘)C++ Primer Plus, Fourth Edition---Using a Dynamic Array
- C++ Primer Plus 读书笔记 (1 -2 章)
- C++ Primer Plus 第四章 复合类型
- [c++ primer plus]使用标准流格式化输入
- [c++ primer plus]常用的const及const的语意
- C++ primer plus 第五版 6章4题
- C++ Primer Plus 第一章 预备知识
- C++ Primer Plus 第二章 开始学习C++
- [c++ primer plus]c++ compiler缺省生成了哪些构造函数?关于构造函数的注意事项。
- [学习笔记][C++Primer Plus]String类的使用
- C++ primer plus 5章9题
- 《C++.Primer.Plus》学习笔记(二)