博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
完善String类([]、 +、 += 运算符重载)、>>和<<运算符重载
阅读量:6990 次
发布时间:2019-06-27

本文共 4232 字,大约阅读时间需要 14 分钟。

在前面文章中使用过几次String类的例子,现在多重载几个运算符,更加完善一下,并且重载流类运算符。

[]运算符重载

+运算符重载

+=运算符重载

<<运算符重载

>>运算符重载

String.h:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 
#ifndef _STRING_H_
#define _STRING_H_
#include <iostream>
using namespace std;
class String
{
public:
    String(const char *str = "");
    String(const String &other);
    String &operator=(const String &other);
    String &operator=(const char *str);
    bool operator!() const;
    char &operator[](unsigned int index);
    const char &operator[](unsigned int index) const;
    friend String operator+(const String &s1, const String &s2);
    String &operator+=(const String &other);
    friend ostream &operator<<(ostream &os, const String &str);
    friend istream &operator>>(istream &is, String &str);
    ~String(void);
    void Display() const;
    int Length() const;
    bool IsEmpty() const;
private:
    String &Assign(const char *str);
    char *AllocAndCpy(const char *str);
    char *str_;
};
#endif // _STRING_H_

String.cpp:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
 
#pragma warning(disable:4996)
#include "String.h"
#include <string.h>
//#include <iostream>
//using namespace std;
String::String(const char *str)
{
    str_ = AllocAndCpy(str);
}
String::String(const String &other)
{
    str_ = AllocAndCpy(other.str_);
}
String &String::operator=(const String &other)
{
    if (this == &other)
        return *this;
    return Assign(other.str_);
}
String &String::operator=(const char *str)
{
    return Assign(str);
}
String &String::Assign(const char *str)
{
    delete[] str_;
    str_ = AllocAndCpy(str);
    return *this;
}
bool String::operator!() const
{
    return strlen(str_) != 0;
}
char &String::operator[](unsigned int index)
{
    //return str_[index];
    //non const 版本调用 const版本
    return const_cast<char &>(static_cast<const String &>(*this)[index]);
}
const char &String::operator[](unsigned int index) const
{
    return str_[index];
}
String::~String()
{
    delete[] str_;
}
char *String::AllocAndCpy(const char *str)
{
    int len = strlen(str) + 1;
    char *newstr = new char[len];
    memset(newstr, 0, len);
    strcpy(newstr, str);
    return newstr;
}
void String::Display() const
{
    cout << str_ << endl;
}
int String::Length() const
{
    return strlen(str_);
}
bool String::IsEmpty() const
{
    return Length() == 0;
}
String operator+(const String &s1, const String &s2)
{
    //int len = strlen(s1.str_) + strlen(s2.str_) + 1;
    //char* newstr = new char[len];
    //memset(newstr, 0, len);
    //strcpy(newstr, s1.str_);
    //strcat(newstr, s2.str_);
    //
    //String tmp(newstr);
    //delete newstr;
    String str = s1;
    str += s2;
    return str;
}
String &String::operator+=(const String &other)
{
    int len = strlen(str_) + strlen(other.str_) + 1;
    char *newstr = new char[len];
    memset(newstr, 0, len);
    strcpy(newstr, str_);
    strcat(newstr, other.str_);
    delete[] str_;
    str_ = newstr;
    return *this;
}
ostream &operator<<(ostream &os, const String &str)
{
    os << str.str_;
    return os;
}
istream &operator>>(istream &is, String &str)
{
    char tmp[1024];
    cin >> tmp;
    str = tmp;
    return is;
}

main.cpp:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 
#include "String.h"
#include <iostream>
using namespace std;
int main(void)
{
    String s1("abcdefg");
    char ch = s1[2];
    cout << ch << endl;
    s1[2] = 'A';
    s1.Display();
    const String s2("xyzabc");
    ch = s2[2];
    //s2[2] = 'M'; Error
    s2.Display();
    String s3 = "xxx";
    String s4 = "yyy";
    String s5 = s3 + s4;
    s5.Display();
    String s6 = "aaa" + s3 + "sdfadfa" + "xxxx";
    s6.Display();
    s3 += s4;
    s3.Display();
    cout << s3 << endl;
    String s7;
    cin >> s7;
    cout << s7 << endl;
if (!s7.IsEmpty())
cout<<s7.Length()<<endl;
    
return 0;
}

需要注意的是,不能将String类的构造函数声明为explicit,否则"xxx"; 编译出错;operator[] 的non const 版本调用了const 版本的实现,其中使用了static_cast和 const_cast 两种类型转换操作符,可以参考;operator+ 调用了operator+= 的实现;只能将流类运算符重载为友元函数,因为第一个参数是流类引用,不是String 类。

通过实现这样一个字符串类,我们可以熟悉基本的内存管理与拷贝控制。

 

参考:

C++ primer 第四版

Effective C++ 3rd
C++编程规范

你可能感兴趣的文章
学习java 想成为合格Java软件工程师所要具备哪些专业技能
查看>>
想要提高日常办公效率?这几款软件利器帮助你武装自己!
查看>>
好程序员大数据技术分享:Zookeeper集群管理与选举
查看>>
怎么找到相似Graph?DeepMind提出超越GNN的图匹配网络
查看>>
【2013年总结】思维跌宕起伏,生命颠簸曲折的一年
查看>>
Oracle管理存储架构(一)--概念
查看>>
Centos7系统下Docker ce的安装及镜像加速
查看>>
在老男孩学习的一点想法
查看>>
戴文的Linux内核专题:04安全
查看>>
C# 密封类和密封方法
查看>>
debian 8.4日常问题处理
查看>>
我的友情链接
查看>>
android系统中的文件系统
查看>>
.NET Core 配置
查看>>
linux下安装配置JDK+Tomcat+Mysql测试环境
查看>>
2008 屏保
查看>>
我的友情链接
查看>>
nginx 负载均衡proxy 配置
查看>>
linux系统中yum服务器的配置
查看>>
如何使用python语言而辩论
查看>>