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

[]运算符重载

+运算符重载

+=运算符重载

<<运算符重载
>>运算符重载

 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

 
#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;

private:

    String &Assign(
const 
char *str);

    
char *AllocAndCpy(
const 
char *str);

    
char *str_;

};

#endif 
// _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

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

 
#pragma warning(disable:
)


#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_) != 
;

}

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) + 
;

    
char *newstr = 
new 
char[len];

    memset(newstr, 
, len);

    strcpy(newstr, str);

return newstr;

}

void String::Display() 
const

{

    cout << str_ << endl;

}

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;
    
//return tmp;
    String str = s1;

    str += s2;

    
return str;

}

String &String::
operator+=(
const String &other)

{

    
int len = strlen(str_) + strlen(other.str_) + 
;

    
char *newstr = 
new 
char[len];

    memset(newstr, 
, 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[
];

    is >> tmp;

    str = tmp;

    
return is;

}

 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[
];

    cout << ch << endl;

s1[
] = 
'A';

    s1.Display();

const String s2(
"xyzabc");

    ch = s2[
];

    
//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;

return 
;

}

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

从零开始学C++之运算符重载(三):完善String类([]、 +、 += 运算符重载)、>>和<<运算符重载的更多相关文章

  1. 完善String类([]、 +、 += 运算符重载)、>>和<<运算符重载

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

  2. 【高德地图API】从零开始学高德JS API(三)覆盖物——标注|折线|多边形|信息窗口|聚合marker|麻点图|图片覆盖物

    原文:[高德地图API]从零开始学高德JS API(三)覆盖物——标注|折线|多边形|信息窗口|聚合marker|麻点图|图片覆盖物 摘要:覆盖物,是一张地图的灵魂.有覆盖物的地图,才是完整的地图.在 ...

  3. 从零开始学 Web 之 JavaScript(三)函数

    大家好,这里是「 Daotin的梦呓 」从零开始学 Web 系列教程.此文首发于「 Daotin的梦呓 」公众号,欢迎大家订阅关注.在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识 ...

  4. 从零开始学 Web 之 Ajax(三)Ajax 概述,快速上手

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  5. 从零开始学 Web 之 ES6(三)ES6基础语法一

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  6. 从零开始学 Web 之 CSS(三)链接伪类、背景、行高、盒子模型、浮动

    大家好,这里是「 Daotin的梦呓 」从零开始学 Web 系列教程.此文首发于「 Daotin的梦呓 」公众号,欢迎大家订阅关注.在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识 ...

  7. 从零开始学 Web 之 HTML(三)表单

    大家好,这里是「 Daotin的梦呓 」从零开始学 Web 系列教程.此文首发于「 Daotin的梦呓 」公众号,欢迎大家订阅关注.在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识 ...

  8. 从零开始学 Web 之 BOM(三)offset,scroll,变速动画函数

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  9. 从零开始学 Web 之 jQuery(三)元素操作,链式编程,动画方法

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

随机推荐

  1. sql注入工具sqlmap使用参数说明

    Options(选项):--version 显示程序的版本号并退出-h, --help 显示此帮助消息并退出-v VERBOSE 详细级别:0-6(默认为1)Target(目标):以下至少需要设置其中 ...

  2. 单元测试之Qunit

    单元测试之Qunit 前言 因为公司开发了一套javascript SDK需要测试,在网上找了很久,找到了JQuery团队开发的QUnit,和基于JUnit的JsUnit,还有一些还没有看,先讲讲QU ...

  3. SQL点滴35—SQL语句中的exists

    原文:SQL点滴35-SQL语句中的exists 比如在Northwind数据库中有一个查询为 SELECT c.CustomerId,CompanyName FROM Customers c WHE ...

  4. PHP 4:从Login进一步看到的

    原文:PHP 4:从Login进一步看到的 我们已经在PHP 3:从Login界面谈PHP标记谈到了PHP标记,不过其页面代码有一句 require_once('bookmark_fns.php'); ...

  5. FFT 的C 语言

    FFT 的C 语言 说好的C 语言实现.必须搞定它! 理论介绍: http://blog.csdn.net/cinmyheart/article/details/39052739 这里有之前matla ...

  6. office编程必不可少

    原文:office编程必不可少 [转] 1. 微软官方实例: 段落.表格.图表 HOW TO:利用 Visual C# .NET 使 Word 自动新建文档 2. 学习资源 (1)Word in th ...

  7. Android AES加密算法,现在实际上

    昨天,老板让我来看看android加密算法.于是在网上找了找,发现AES加密算法.(当然,MD5,BASE64什么http://snowolf.iteye.com/blog/379860这篇文章列举了 ...

  8. Windows Live Writer 完成开源并推出开源分支

    原文:Announcing Open Live Writer - An Open Source Fork of Windows Live Writer Windows Live Writer是一款发布 ...

  9. C#打包应用程序

    摘要:本文介绍在C#中手把手教你用C#打包应用程序(安装程序卸载程序) 1:新建安装部署项目 打开VS,点击新建项目,选择:其他项目类型->安装与部署->安装向导(安装项目也一样),然后点 ...

  10. CRM 2013 切换显示语言

    想要更改显示需要,必须在服务器上安装语言包.不过语言包中仅包含系统的实体和字段的翻译,想要自定义的实体字段根据选择的语言变化,必须做好实体字段的翻译. 安装好语言包后,找到设置->管理-> ...