在前面文章中使用过几次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. phpStorm+XDebug+chrome 配置

    运行环境: phpStorm 10.0.1 PHP 5.6.24 VC11 x86 Thread Safe Xdebug 2.4.1(PHP 5.6 VC11 TS (32 bit) 1. PHP安装 ...

  2. 用javascript把扑克牌理理顺!

    打扑克的人都知道,比如斗地主! 我们一般都会按照顺序把随机摸过来的牌从小到大的顺序在手上理整齐(记得小时候打牌两副牌手都抓不过来),这篇随笔就是想通过实现这个功能来熟悉下js中排序数组等相关知识. 用 ...

  3. 探讨javascript面向对象编程

    (个人blog迁移文章.) 前言: 下面将探讨javascript面向对象编程的知识. 请不要刻意把javascript想成面向对象编程是理所当然的. javascript里面,对象思想不可少,但是不 ...

  4. Windows 8.1 store app 开发笔记

    原文:Windows 8.1 store app 开发笔记 零.简介 一切都要从博彦之星比赛说起.今年比赛的主题是使用Bing API(主要提到的有Bing Map API.Bing Translat ...

  5. Unity3D第三人称摄像机控制脚本

    好久没有敲Blog该.感谢您的留言.注意.私人信件和其他支持,但我似乎没有办法继续自己曾经写了一篇博客系列,因为我在网上找到有关unity3D太少的内容,U3D相关的文章!.. 第三人称视角 第三人称 ...

  6. Android多画面幻灯片:ViewPager基础上,利用与PagerTabStrip出生缺陷(源代码)

    近期使用ViewPager.读了几个人说是不是很清晰的信息,干脆自己写demo总结下. 样例非常easy.Activity里有三个界面能够滑动.每个界面都有一个button并设置好了监听.PagerT ...

  7. SSIS如何引用外部DLL

    原文:SSIS如何引用外部DLL 当SSIS引用外部的DLL时,外部的DLL须满足以下条件: 1. DLL是强命名. 2. 加入到GAC (C:\WINDOWS\assembly),直接把DLL拉进目 ...

  8. 用css样式围剿等高列问题(转载)

    明修栈道暗度陈仓 该秘籍的心法只有十二个字:”隐藏容器溢出,正负内外边距.”看完下面的几行代码,再看这句话你真的可以看到圣光! 隐藏容器溢出.将外层容器的溢出设为隐藏: .container { ov ...

  9. 查询职责分离(CQRS)模式

    查询职责分离(CQRS)模式 在常用的三层架构中,通常都是通过数据访问层来修改或者查询数据,一般修改和查询使用的是相同的实体.在一些业务逻辑简单的系统中可能没有什么问题,但是随着系统逻辑变得复杂,用户 ...

  10. 应用CSS的page-break-after属性 实现WEB页面强制分页打印

    虽然dedecms.com向大家介绍了很多CSS属性的相关知识,但有些非常冷门的属性还是有所欠缺.在B/S程序中,对打印页面的控制,CSS相对比较弱,例如: 自动分页, 就基本没啥实际用途.我们通常需 ...