面向对象程序设计第二次实验课——mystring类实现
来源:互联网 发布:淘宝电击棍 编辑:程序博客网 时间:2024/05/16 05:36
#pragma once#include <cstring>#include <iostream>using namespace std;const size_t MAX_CHAR_IN_NODE = 100;// 定义链块 struct Node { char s[MAX_CHAR_IN_NODE]; Node *next;};class myString;myString operator+ (const myString& lhs, const myString& rhs);class myString { friend myString operator+ (const myString& lhs, const myString& rhs); friend ostream& operator<< (ostream& out, const myString& rhs); public: myString(void); myString(const char *s); myString(const myString& ms); ~myString(void); myString& operator= (const myString& rhs); myString& operator+= (const myString& rhs); const char& operator[] (size_t index) const; char& operator[] (size_t index); myString operator() (size_t l, size_t r) const; size_t len(void) const {return len_;} private: Node *head_; // 链块头指针 size_t cntNode_; // the num of Node size_t len_; // the length of string};
#include "myString.h"ostream& operator<< (ostream& out, const myString& rhs){ for (Node *p = rhs.head_; p; p = p -> next) { for (size_t i = 0; i < MAX_CHAR_IN_NODE; i ++) if (p->s[i] != '\0') cout << p -> s[i]; else break; } return out;}myString operator+ (const myString& lhs, const myString& rhs){ myString ret(lhs); ret += rhs; return ret;} myString::myString(void) : cntNode_(1), len_(0) { head_ = new Node; head_ -> s[0] = '\0'; head_ -> next = NULL;}myString::myString(const myString& ms) : cntNode_(ms.cntNode_), len_(ms.len_){ // 创建链块 head_ = new Node; head_ -> next = NULL; Node *q = head_; for (size_t i = 1; i < cntNode_; i ++) { Node *p = new Node; q -> next = p; p -> next = NULL; q = q -> next; } // 进行拷贝 for (Node *p = head_, *q = ms.head_; q; p = p -> next, q = q -> next) { strcpy(p->s, q->s); }}myString::myString(const char *s){ // 计算参数 len_ = strlen(s); cntNode_ = (len_ + 1) / MAX_CHAR_IN_NODE; if ((len_ + 1) % MAX_CHAR_IN_NODE) ++ cntNode_; // 创建链块 head_ = new Node; head_ -> next = NULL; Node *q = head_; for (size_t i = 1; i < cntNode_; i ++) { Node *p = new Node; q -> next = p; p -> next = NULL; q = q -> next; } // 进行拷贝 size_t cnt = 0; for (Node *p = head_; p; p = p -> next, cnt += 100) { for (size_t i = 0; i < MAX_CHAR_IN_NODE; i ++) { if (s[i + cnt] != '\0') p->s[i] = s[i + cnt]; else { p->s[i] = '\0'; break; } } }}myString::~myString(void){ Node *p = head_; for (Node *q = head_ -> next; q; p = q, q = q -> next) { delete p; } delete p;}myString& myString::operator= (const myString& rhs){ if (this != &rhs) { len_ = rhs.len_; cntNode_ = rhs.cntNode_; head_ = new Node; head_ -> next = NULL; Node *q = head_; for (size_t i = 1; i < cntNode_; i ++) { Node *p = new Node; q -> next = p; p -> next = NULL; q = q -> next; } for (Node *p = head_, *q = rhs.head_; q; p = p -> next, q = q -> next) { strcpy(p->s, q->s); } } return *this;}myString& myString::operator+= (const myString& rhs){ if (rhs.len_ == 0) return *this; // 计算参数 size_t loc = (len_) % MAX_CHAR_IN_NODE; len_ = len_ + rhs.len_; size_t preCntNode_ = cntNode_; cntNode_ = (len_ + 1) / MAX_CHAR_IN_NODE; if ((len_ + 1) % MAX_CHAR_IN_NODE) ++ cntNode_; Node *p = head_; for (Node *q = head_ -> next; q; p = q, q = q -> next) ; //空循环,寻找拷贝的位置 // 如果需要额外空间,申请之 Node *r = p; for (size_t i = preCntNode_; i < cntNode_; i ++) { Node *q = new Node; q -> next = NULL; p -> next = q; p = p -> next; } // 进行拷贝 p = r; for (Node *q = rhs.head_; q; q = q -> next) { for (size_t i = 0; i < MAX_CHAR_IN_NODE; i ++) { if (q->s[i] != '\0') p->s[loc ++] = q->s[i]; else { p->s[loc] = '\0'; break; } if (loc == MAX_CHAR_IN_NODE) { loc = 0; p = p -> next; } } } return *this;}char& myString::operator[] (size_t index){ if (index < len_) { size_t block = index / MAX_CHAR_IN_NODE; size_t loc = index % MAX_CHAR_IN_NODE; size_t i = 0; Node *p; for (p = head_; i < block; p = p->next, ++ i) ;//空循环 return p -> s[loc]; } else { // 越界返回第一个 return head_ -> s[0]; }}const char& myString::operator[] (size_t index) const{ if (index < len_) { size_t block = index / MAX_CHAR_IN_NODE; size_t loc = index % MAX_CHAR_IN_NODE; size_t i = 0; Node *p; for (p = head_; i < block; p = p->next, ++ i) ;//空循环 return p -> s[loc]; } else { return head_ -> s[0]; }}myString myString::operator() (size_t l, size_t r) const{ if (l >= 1 && r <= len_ && l <= r) { char *s = new char[r - l + 2]; for (size_t i = 0; i < r - l + 1; i ++) { s[i] = (*this)[l + i - 1]; } s[r - l + 1] = '\0'; myString ret(s); delete []s; return ret; } else { return myString(); }}
#include <iostream>#include <string>#include "myString.h"using namespace std;/* run this program using the console pauser or add your own getch, system("pause") or input loop */int main(int argc, char** argv) { myString s1; cout << s1 << endl; myString s2("hello"); cout << s2 << endl; s1 += s2; cout << s1 << endl; cout << s1 + s2 << endl; cout << s1[1] << endl; cout << endl << endl; cout << endl; myString m("Software"); myString n(m),o; o = m; cout << n[4] << endl; cout << n.len() << endl; o = m + n; cout << o << endl; o = m(2,8); cout << o << endl; const myString s10(m); cout << s10[4] << endl; myString s("10110111011110111110111111011111110111111110111111111011111111110111111111110111111111111011111111111110"); cout << s[101] << endl; cout << s.len() << endl; cout << s << endl; myString ss(s); cout << ss << endl; cout << ss + s << endl; return 0;}
第二次实验报告
一、 题目分析
myString m(“Software”);
myString n(m),o;
o = m;
cout << n[4] << endl;
cout << n.len() << endl;
o = m + n;
cout << o << endl;
o = m(2,8);
cout << o << endl;
ppt上的代码已经很清楚的说明了这次实验的要求,显然,就算没有要求,一个类也应该提供默认构造函数、拷贝构造函数、=运算符重载以及析构函数。此外,由第一行可以得出,应该有一个参数为C风格字符串的构造函数。第四行说明应该重载下标运算符,第五行要求有一个成员len,可以返回字符串长度,第六行要求重载+运算符,第八行要求重载函数调用运算符,返回字符串的一个子串。
二、 主要流程
首先,定义了一个结构体Node,作为myString类中使用的链块,为了使myString类可以适应各类不同长度的字符串,myString类中使用链块作为数据结构存储字符串。
const size_t MAX_CHAR_IN_NODE = 100;
// 定义链块
struct Node {
char s[MAX_CHAR_IN_NODE];
Node *next;
};
接下来是三个构造函数:
myString(void);
myString(const char *s);
myString(const myString& ms);
构造函数之间并没有委托构造关系,myString(const myString& ms) 调用了strcpy函数。
。
析构函数:
~myString(void);
析构函数负责释放申请的链块的空间。
=运算符重载:
myString& operator= (const myString& rhs);
其同样调用了strcpy函数。
+、+=运算符重载:
myString& operator+= (const myString& rhs);
friend myString operator+ (const myString& lhs, const myString& rhs);
首先实现+=,在+中调用+=。
[]运算符重载:
const char& operator[] (size_t index) const;
char& operator[] (size_t index);
实现了常量版本和非常量版本,互相没有调用关系。
()运算符重载:
myString operator() (size_t l, size_t r) const;
调用了下表运算符函数。
三、 程序难点
1. 实现任意长度的myString类
这里借鉴了stl里string类的思想,使用了链块作为数据结构,当然这也加大了程序实现的难度,在构造、修改、析构的时候都需要考虑到各种情况。
2. +,[]的重载
由于实现方式是链块,在做加法运算时就要重新计算加法后字符串的长度,并基于此决定是否需要更多空间。由于使用了链块,本来容易的取下标操作也变得不那么简单了,需要定位到字符所在的链块,再将其中的某一空间返回。
四、 优点与缺点
1. 优点:
a) 实现了myString类的任意长度的要求
b) 按照要求实现了所有功能
c) 重载了<<运算符,便于输出和调试
2. 缺点:
a) 没有重载关系预算符
b) 由于用到了链块,降低了程序效率
c) 部分代码被多次重用,而没有将其抽象成私有方法
五、 收获
第一次写链块,成功的写出来了还是很开心的,更加深入的了解了stl中string的内部原理,一步一步将C风格字符串封装成了string类型并实现了部分功能。第一次尝试重载()运算符,对于仿函数有了更深入的了解
- 面向对象程序设计第二次实验课——mystring类实现
- 面向对象第二次实验
- 实现MyString类(二)—MyString.cpp实现
- 面向对象程序设计第三次实验课——Wuxing
- 实现MyString类(一)—类声明mystring.h
- 第二次C++实验——简单程序设计
- 【对象数组+静态数据成员+静态成员函数+...】面向对象程序设计(B)——第二次作业
- 第三课--之一(对象)实现MyString类的作业
- 实现MyString类(三)—关于返回对象的说明
- 面向对象程序设计第一次实验课——位运算封装
- 面向对象程序设计第四次实验课——socket初试
- 面向对象程序设计第五次实验课——深拷贝
- 面向对象程序设计第六次实验课——群与子群(装饰模式)
- 面向对象程序设计第七次实验课——状态模式
- 《面向对象程序设计》实验指导书
- Java 实验:面向对象程序设计
- Python类——面向对象程序设计
- 面向对象程序设计核心—类
- PAT-A-1100. Mars Numbers (20)
- JavaScript转换与解析JSON的方法
- linux内存管理中的page
- Git(2)——初始化Git
- ThinkPHP 验证码 页面解析乱码
- 面向对象程序设计第二次实验课——mystring类实现
- POJ3104 Drying
- 缓存管理器
- IO流
- 实验 22 利用三层交换实现以太网建立多个 VLAN
- 1.2HelloWorld
- CentOS Linux解决Device eth0 does not seem to be present
- Git(3)——创建版本库
- c语言编程题目(一)