简单版的String类,旨在说明>> <<重载

  1. #include <iostream>
  2. //#include <cstring>//包含char*的字符串处理函数
  3. using namespace std;
  4.  
  5. class String
  6. {
  7. public:
  8. String(){p=NULL;}
  9. String(char *str);
  10. void diaplay();
  11. friend bool operator>(String &str1,String &str2);//重载>操作符
  12. friend ostream & operator <<(ostream&,String &str);
  13. friend istream & operator >>(istream&,String &str);
  14. private:
  15. char *p;
  16. };
  17. String::String(char *str)
  18. {
  19. p=str;
  20. }
  21. void String::diaplay()
  22. {
  23. cout<<p;
  24. }
  25. bool operator>(String &str1,String &str2)
  26. {
  27. if (strcmp(str1.p,str2.p)>)
  28. {
  29. return true;
  30. }
  31. else return false;
  32. }
  33. ostream& operator <<(ostream& output,String &str)
  34. {
  35. output<<str.p;
  36. return output;
  37. }
  38. istream& operator >>(istream& input,String &str)
  39. {
  40. //input>>str.p;//没有分配空间,无法读入。
  41. str.p=new char[];
  42. input>>str.p;
  43. return input;//
  44. // char q[256];
  45. // input>>q;
  46. // //p.length =strlen(q);
  47. // str.p=new char[strlen(q)+1];
  48. // strcpy(str.p,q);
  49. // return input;
  50.  
  51. }
  52. int main()
  53. {
  54. String str1("Hello,pig!"),str2;
  55. cin>>str2;
  56. str1.diaplay();
  57. bool b=str1>str2;
  58. cout<<'\n'<<b<<endl;
  59. cout<<str2<<endl;
  60. }

重载>> <<函数只能作为类的类的友元函数,其形式如下:

istream& operator >>(istream& ,自定义类 &);

ostream& operator <<(ostream& ,自定义类 &);

重载运算法作为类成员函数还是类友元函数区别:

1 作为类成员函数必须满足运算表达式第一个参数是一个类对象,而且返回值与该对象同类型。

故一般将单目操作符重载为成员函数,双目操作符重载为友元函数。

String 类较完整实现:

  1. #include <iostream>
  2. //#include <cstring>//包含char*的字符串处理函数
  3. using namespace std;
  4.  
  5. class String
  6. {
  7. public:
  8. String(){p=NULL;len=;}
  9. String(int);
  10. String(char *str);
  11. String (String&);
  12. ~String(){delete[] p;}
  13. void Clear();//清空本串
  14. int mystrlen();
  15. bool IsEmpty();//判断本串是否为空
  16. String Substr(int index,int count);//从index开始提取count个字符的字串
  17. int Find(char c,int start);//从下标start开始找到c后,返回字符c 在本串的下标
  18. char & operator [](int i);//重载[]操作符
  19. operator char *();//将String类对象转换为普通字符串
  20.  
  21. friend bool operator>(String &str1,String &str2);//重载>操作符
  22. friend ostream & operator <<(ostream&,String &str);
  23. friend istream & operator >>(istream&,String &str);
  24. private:
  25. char *p;//字符串指针
  26. int len;//字符串长度,不包含最后的\0
  27. };
  28.  
  29. String::String(int length)
  30. {
  31. len=length;
  32. p=new char[length+];
  33. }
  34. String::String(char *str)
  35. {
  36. if (str==NULL)
  37. {
  38. len=;
  39. p=NULL;
  40. }
  41. else
  42. {
  43. len=strlen(str);
  44. p=new char[len+];
  45. strcpy(p,str);//深拷贝
  46. }
  47. //p=str;//只写这个是浅拷贝,只拷贝了指针
  48. }
  49. String::String(String &other)
  50. {
  51. len=other.len;
  52. p=new char[len+];
  53. strcpy(p,other.p);
  54. }
  55. bool String::IsEmpty()
  56. {
  57. return (!this->len);
  58. }
  59.  
  60. void String::Clear()
  61. {
  62. if (!IsEmpty())
  63. {
  64. delete[]p;
  65. len=;
  66. }
  67. }
  68. int String::mystrlen()
  69. {
  70. return len;
  71. }
  72. int String::Find(char c,int start)
  73. {
  74. int i;
  75. if (start>len) cout<<"超出范围"<<endl;
  76. //return NULL;
  77. else
  78. {
  79. for (i =start;i<len;++i)
  80. {
  81. if (p[i]==c) break;
  82. }
  83. return i;
  84.  
  85. }
  86. }
  87. String String::Substr(int index,int count)
  88. {
  89.  
  90. if (index+count>len) cout<<"超出范围"<<endl;
  91. else
  92. {
  93. String str(count);
  94. str.len=count;
  95. for (int i=;i<count;i++,index++)
  96. str.p[i]=p[index];
  97.  
  98. str.p[count]='\0';
  99. return str;
  100. }
  101.  
  102. }
  103. char & String::operator[](int i)
  104. {
  105. if (i<||i>len-)
  106. {
  107. cout<<"越界"<<endl;
  108. }
  109. else
  110. {
  111. return p[i];
  112. }
  113. }
  114. //类型转换
  115. String::operator char *()
  116. {
  117. return (char *)p;
  118. }
  119.  
  120. bool operator>(String &str1,String &str2)
  121. {
  122. if (strcmp(str1.p,str2.p)>)
  123. {
  124. return true;
  125. }
  126. else return false;
  127. }
  128. ostream& operator <<(ostream& output,String &str)
  129. {
  130. output<<str.p;
  131. return output;
  132. }
  133. istream& operator >>(istream& input,String &str)
  134. {
  135. //input>>str.p;//没有分配空间,无法读入。
  136. str.p=new char[];
  137. input>>str.p;
  138. return input;//
  139. //或者:
  140. // char q[256];
  141. // input>>q;
  142. // str.p=new char[strlen(q)+1];
  143. // strcpy(str.p,q);
  144. // return input;
  145.  
  146. }
  147. int main()
  148. {
  149. String str3("hello");
  150. int pos;
  151. cout<<"\n测试Find功能"<<endl;
  152. pos = str3.Find('e',);
  153. cout<<str3<<endl;
  154. cout<<pos<<endl;
  155.  
  156. cout<<"\n测试Substr功能"<<endl;
  157. cout<<str3.Substr(,)<<endl;
  158.  
  159. cout<<"\n测试重载<< >>功能"<<endl;
  160. String c;
  161. cout<<"请输入一段字符串"<<endl;
  162. cin>>c;
  163. cout<<c<<endl;
  164.  
  165. cout<<"测试字符串C函数的应用"<<endl;
  166. String f();
  167. char *e = " this is a test";
  168. char g[]="hahahhah";
  169. strcpy(f,e); //隐含执行了默认类型转换(char *)f;
  170. cout<<f<<endl;
  171. strcat(g,f);
  172. cout<<g<<endl;
  173.  
  174. cout<<"\n测试IsEmpty _strlen功能"<<endl;
  175. String d("tihs is a test");
  176. if(d.IsEmpty())
  177. cout<<"d 是空字符串"<<endl;
  178. else
  179. cout<<"d 非空字符串 \t长度:"<<d.mystrlen()<<endl;
  180.  
  181. return ;
  182.  
  183. }

注意:C++标准库中string类构造函数是浅拷贝,

string a="hello";
 string b(a);
 cout<<(void *)a[2]<<endl;
 cout<<(void *)b[2]<<endl; 地址形同

注意:operator char *();//将String类对象转换为普通字符串

是类型转换函数的定义,即该类型可以自动转换为const char*类型。

像是隐式类型转换

不同于重载*,重载*应写为 char operator * ();

因为运算符重载中有几个运算符的返回值是有格式的(约定),如operator * 在重载时通常返回值是classType&或者const classType& 。
operator const char*() const是类型转换函数的定义,即该类型可以自动转换为const char*类型。至于最后一个const,那个大家都知道是对类成员的限制(不允许更改对象的状态)
比如我们现在自定一个一个整型(MyInt),它允许在需要使用C++语言中的int类型时将MyInt类型转换为int类型:
class MyInt {
     public:
          operator int () const;
     private:
          int elem;
};
MyInt::operator int () const
{
    return elem;
}
就可以在需要使用int类型时使用MyInt。
需要记住,C++中没有返回类型的函数有3个,构造函数、析构函数、类型转换函数。

前两个是不写返回类型函数实现中也不允许出现return语句
最后一个则是不写返回类型,但是必须返回对应类型的值,即必须出现return语句。

类型转换中返回类型在operator后面在括号前面,且没有参数。

函数运算符中是类型在operator 前面

String 类实现 以及>> <<流插入/流提取运算符重载的更多相关文章

  1. C++ 流插入"<<"和流提取">>"运算符的重载

    01 流插入<<运算符的重载 C++ 在输出内容时,最常用的方式: std::cout << 1 <<"hello"; 问题: 那这条语句为什么 ...

  2. C++重载流插入运算符和流提取运算符【转】

    C++的流插入运算符“<<”和流提取运算符“>>”是C++在类库中提供的,所有C++编译系统都在类库中提供输入流类istream和输出流类ostream.cin和cout分别是 ...

  3. Java的String类

    String类 String是引用数据类型:字符串是String类的对象 String类的构造方法 共有13种重载方式,这里只示例常用的几个 String():创建一个空字符串 String(Stri ...

  4. 关于如何来构造一个String类

    今天帮着一位大二的学弟写了一个String的类,后来一想这个技术点,也许不是什么难点,但是还是简单的记录一些吧! 为那些还在路上爬行的行者,剖析一些基本的实现..... 内容写的过于简单,没有涉及到其 ...

  5. string类中运算符重载实现

    C++中预定义的加.减等运算符的操作对象只能是基本的数据类型.如果要在用户自定义的类型对象上应用同样的运算符,就需要通过运算符重载来重新定义其实现,使它能够用于自定义类型执行特定的操作,所以运算符重载 ...

  6. C++学习6-面向对象编程基础(运算符重载、类的派生与继承、命名空间)

    运算符重载 重载的运算符是具有特殊名字的函数:它们的名字由关键字operator和其后要定义的运算符号共同组成.重载的运算符是遵循函数重载的选择原则,根据不同类型或不同参数来选择不同的重载运算符. 运 ...

  7. 编码实现字符串类CNString实现运算符重载

    题目描述: 编码实现字符串类CNString,该类有默认构造函数.类的拷贝函数.类的析构函数及运算符重载,需实现以下"="运算符."+"运算."[]& ...

  8. C++11运算符重载详解与向量类重载实例(<<,>>,+,-,*等)

    1. C++运算符重载介绍 C ++ 中预定义的运算符的操作对象只能是基本数据类型.但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作.这时就必须在C ++ 中重新定义这些运算符,赋予已 ...

  9. -1-4 java io java流 常用流 分类 File类 文件 字节流 字符流 缓冲流 内存操作流 合并序列流

      File类 •文件和目录路径名的抽象表示形式 构造方法 •public File(String pathname) •public File(String parent,Stringchild) ...

随机推荐

  1. asp.net Core EF core ( Entity Framework 7 ) 数据库更新维护

    CreateData­baseIfNotExists等之前的API已经废弃,现在采用的是微软封装好,简化.高效的API,migrations 因为,旧API,要付出高昂的代价,以及局限性 打开VS20 ...

  2. Aspose.Words对于Word的操作

    对于word操作一般是对已有word模板的操作,直接新建的不考虑,网上教程很多,自己看吧一般有以下几种办法(忘了具体几种了,一般情况下以下就够了)1.通过书签替换顾名思义,就是先定义一个书签,然后在书 ...

  3. R绘图系统中的坐标系

    在R语言中,对于图中的点来说,有很多种坐标系来进行定位 举个例子: par(omi = c(1, 1, 1, 1), mai = c(1, 1, 1, 1), mfrow = c(1, 2)) plo ...

  4. Yii2 cache的用法(1)

    数据缓存需要缓存组件提供支持,它代表各种缓存存储器, 例如内存,文件,数据库. 'components' => [ 'cache' => [ 'class' => 'yii\cach ...

  5. js中的方法调用

    <script> var m = {com: { sao: {citi:{}}}}; m.com.sao.citi.init = new function() { this.name = ...

  6. ESB架构之企业实施案例

    ESB架构之企业实施案例 ESB解决令企业最头痛的信息系统整合问题 SOA 架构中的ESB是更好的应用于异构系统集成整合还是用于统一服务调用/基础服务实施

  7. jenkins 升级jdk到1.8.0 报java.io.IOException:Unable to read /var/lib/jenkins/config.xml

    今天手动下载安装了jdk1.8.0, 并修改了配置文件,当前默认使用该版本的jdk.但是报出一下错误: 问题查到: https://issues.jenkins-ci.org/browse/JENKI ...

  8. WebGL 颜色与纹理

    1.纹理坐标 纹理坐标是纹理图像上的坐标,通过纹理坐标可以在纹理图像上获取纹理颜色.WebGL系统中的纹理坐标系统是二维的,如图所示.为了将纹理坐标和广泛使用的x.y坐标区分开来,WebGL使用s和t ...

  9. IT规划,是否一定要梳理流程

    IT规划,是面向企业业务的 IT战略规划,必然需要考虑业务的运营特点和需求.以往为企业提供IT规划咨询服务时,很多企业都提出,IT规划要满足业务的需求,那就要对业务足够熟 悉,而通过梳理流程能够达到这 ...

  10. mysql中使用show variables同时查询多个参数值?show variables的使用?

    需求描述: 今天在查mysq关于连接数的问题,想要通过一个show variables命令同时查出来多个值.在此记录下. 操作过程: 1.通过show variables语句的like可以匹配多个值或 ...