String 类实现 以及>> <<流插入/流提取运算符重载
简单版的String类,旨在说明>> <<重载
- #include <iostream>
- //#include <cstring>//包含char*的字符串处理函数
- using namespace std;
- class String
- {
- public:
- String(){p=NULL;}
- String(char *str);
- void diaplay();
- friend bool operator>(String &str1,String &str2);//重载>操作符
- friend ostream & operator <<(ostream&,String &str);
- friend istream & operator >>(istream&,String &str);
- private:
- char *p;
- };
- String::String(char *str)
- {
- p=str;
- }
- void String::diaplay()
- {
- cout<<p;
- }
- bool operator>(String &str1,String &str2)
- {
- if (strcmp(str1.p,str2.p)>)
- {
- return true;
- }
- else return false;
- }
- ostream& operator <<(ostream& output,String &str)
- {
- output<<str.p;
- return output;
- }
- istream& operator >>(istream& input,String &str)
- {
- //input>>str.p;//没有分配空间,无法读入。
- str.p=new char[];
- input>>str.p;
- return input;//
- // char q[256];
- // input>>q;
- // //p.length =strlen(q);
- // str.p=new char[strlen(q)+1];
- // strcpy(str.p,q);
- // return input;
- }
- int main()
- {
- String str1("Hello,pig!"),str2;
- cin>>str2;
- str1.diaplay();
- bool b=str1>str2;
- cout<<'\n'<<b<<endl;
- cout<<str2<<endl;
- }
重载>> <<函数只能作为类的类的友元函数,其形式如下:
istream& operator >>(istream& ,自定义类 &);
ostream& operator <<(ostream& ,自定义类 &);
重载运算法作为类成员函数还是类友元函数区别:
1 作为类成员函数必须满足运算表达式第一个参数是一个类对象,而且返回值与该对象同类型。
故一般将单目操作符重载为成员函数,双目操作符重载为友元函数。
String 类较完整实现:
- #include <iostream>
- //#include <cstring>//包含char*的字符串处理函数
- using namespace std;
- class String
- {
- public:
- String(){p=NULL;len=;}
- String(int);
- String(char *str);
- String (String&);
- ~String(){delete[] p;}
- void Clear();//清空本串
- int mystrlen();
- bool IsEmpty();//判断本串是否为空
- String Substr(int index,int count);//从index开始提取count个字符的字串
- int Find(char c,int start);//从下标start开始找到c后,返回字符c 在本串的下标
- char & operator [](int i);//重载[]操作符
- operator char *();//将String类对象转换为普通字符串
- friend bool operator>(String &str1,String &str2);//重载>操作符
- friend ostream & operator <<(ostream&,String &str);
- friend istream & operator >>(istream&,String &str);
- private:
- char *p;//字符串指针
- int len;//字符串长度,不包含最后的\0
- };
- String::String(int length)
- {
- len=length;
- p=new char[length+];
- }
- String::String(char *str)
- {
- if (str==NULL)
- {
- len=;
- p=NULL;
- }
- else
- {
- len=strlen(str);
- p=new char[len+];
- strcpy(p,str);//深拷贝
- }
- //p=str;//只写这个是浅拷贝,只拷贝了指针
- }
- String::String(String &other)
- {
- len=other.len;
- p=new char[len+];
- strcpy(p,other.p);
- }
- bool String::IsEmpty()
- {
- return (!this->len);
- }
- void String::Clear()
- {
- if (!IsEmpty())
- {
- delete[]p;
- len=;
- }
- }
- int String::mystrlen()
- {
- return len;
- }
- int String::Find(char c,int start)
- {
- int i;
- if (start>len) cout<<"超出范围"<<endl;
- //return NULL;
- else
- {
- for (i =start;i<len;++i)
- {
- if (p[i]==c) break;
- }
- return i;
- }
- }
- String String::Substr(int index,int count)
- {
- if (index+count>len) cout<<"超出范围"<<endl;
- else
- {
- String str(count);
- str.len=count;
- for (int i=;i<count;i++,index++)
- str.p[i]=p[index];
- str.p[count]='\0';
- return str;
- }
- }
- char & String::operator[](int i)
- {
- if (i<||i>len-)
- {
- cout<<"越界"<<endl;
- }
- else
- {
- return p[i];
- }
- }
- //类型转换
- String::operator char *()
- {
- return (char *)p;
- }
- bool operator>(String &str1,String &str2)
- {
- if (strcmp(str1.p,str2.p)>)
- {
- return true;
- }
- else return false;
- }
- ostream& operator <<(ostream& output,String &str)
- {
- output<<str.p;
- return output;
- }
- istream& operator >>(istream& input,String &str)
- {
- //input>>str.p;//没有分配空间,无法读入。
- str.p=new char[];
- input>>str.p;
- return input;//
- //或者:
- // char q[256];
- // input>>q;
- // str.p=new char[strlen(q)+1];
- // strcpy(str.p,q);
- // return input;
- }
- int main()
- {
- String str3("hello");
- int pos;
- cout<<"\n测试Find功能"<<endl;
- pos = str3.Find('e',);
- cout<<str3<<endl;
- cout<<pos<<endl;
- cout<<"\n测试Substr功能"<<endl;
- cout<<str3.Substr(,)<<endl;
- cout<<"\n测试重载<< >>功能"<<endl;
- String c;
- cout<<"请输入一段字符串"<<endl;
- cin>>c;
- cout<<c<<endl;
- cout<<"测试字符串C函数的应用"<<endl;
- String f();
- char *e = " this is a test";
- char g[]="hahahhah";
- strcpy(f,e); //隐含执行了默认类型转换(char *)f;
- cout<<f<<endl;
- strcat(g,f);
- cout<<g<<endl;
- cout<<"\n测试IsEmpty _strlen功能"<<endl;
- String d("tihs is a test");
- if(d.IsEmpty())
- cout<<"d 是空字符串"<<endl;
- else
- cout<<"d 非空字符串 \t长度:"<<d.mystrlen()<<endl;
- return ;
- }
注意: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 类实现 以及>> <<流插入/流提取运算符重载的更多相关文章
- C++ 流插入"<<"和流提取">>"运算符的重载
01 流插入<<运算符的重载 C++ 在输出内容时,最常用的方式: std::cout << 1 <<"hello"; 问题: 那这条语句为什么 ...
- C++重载流插入运算符和流提取运算符【转】
C++的流插入运算符“<<”和流提取运算符“>>”是C++在类库中提供的,所有C++编译系统都在类库中提供输入流类istream和输出流类ostream.cin和cout分别是 ...
- Java的String类
String类 String是引用数据类型:字符串是String类的对象 String类的构造方法 共有13种重载方式,这里只示例常用的几个 String():创建一个空字符串 String(Stri ...
- 关于如何来构造一个String类
今天帮着一位大二的学弟写了一个String的类,后来一想这个技术点,也许不是什么难点,但是还是简单的记录一些吧! 为那些还在路上爬行的行者,剖析一些基本的实现..... 内容写的过于简单,没有涉及到其 ...
- string类中运算符重载实现
C++中预定义的加.减等运算符的操作对象只能是基本的数据类型.如果要在用户自定义的类型对象上应用同样的运算符,就需要通过运算符重载来重新定义其实现,使它能够用于自定义类型执行特定的操作,所以运算符重载 ...
- C++学习6-面向对象编程基础(运算符重载、类的派生与继承、命名空间)
运算符重载 重载的运算符是具有特殊名字的函数:它们的名字由关键字operator和其后要定义的运算符号共同组成.重载的运算符是遵循函数重载的选择原则,根据不同类型或不同参数来选择不同的重载运算符. 运 ...
- 编码实现字符串类CNString实现运算符重载
题目描述: 编码实现字符串类CNString,该类有默认构造函数.类的拷贝函数.类的析构函数及运算符重载,需实现以下"="运算符."+"运算."[]& ...
- C++11运算符重载详解与向量类重载实例(<<,>>,+,-,*等)
1. C++运算符重载介绍 C ++ 中预定义的运算符的操作对象只能是基本数据类型.但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作.这时就必须在C ++ 中重新定义这些运算符,赋予已 ...
- -1-4 java io java流 常用流 分类 File类 文件 字节流 字符流 缓冲流 内存操作流 合并序列流
File类 •文件和目录路径名的抽象表示形式 构造方法 •public File(String pathname) •public File(String parent,Stringchild) ...
随机推荐
- asp.net Core EF core ( Entity Framework 7 ) 数据库更新维护
CreateDatabaseIfNotExists等之前的API已经废弃,现在采用的是微软封装好,简化.高效的API,migrations 因为,旧API,要付出高昂的代价,以及局限性 打开VS20 ...
- Aspose.Words对于Word的操作
对于word操作一般是对已有word模板的操作,直接新建的不考虑,网上教程很多,自己看吧一般有以下几种办法(忘了具体几种了,一般情况下以下就够了)1.通过书签替换顾名思义,就是先定义一个书签,然后在书 ...
- R绘图系统中的坐标系
在R语言中,对于图中的点来说,有很多种坐标系来进行定位 举个例子: par(omi = c(1, 1, 1, 1), mai = c(1, 1, 1, 1), mfrow = c(1, 2)) plo ...
- Yii2 cache的用法(1)
数据缓存需要缓存组件提供支持,它代表各种缓存存储器, 例如内存,文件,数据库. 'components' => [ 'cache' => [ 'class' => 'yii\cach ...
- js中的方法调用
<script> var m = {com: { sao: {citi:{}}}}; m.com.sao.citi.init = new function() { this.name = ...
- ESB架构之企业实施案例
ESB架构之企业实施案例 ESB解决令企业最头痛的信息系统整合问题 SOA 架构中的ESB是更好的应用于异构系统集成整合还是用于统一服务调用/基础服务实施
- 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 ...
- WebGL 颜色与纹理
1.纹理坐标 纹理坐标是纹理图像上的坐标,通过纹理坐标可以在纹理图像上获取纹理颜色.WebGL系统中的纹理坐标系统是二维的,如图所示.为了将纹理坐标和广泛使用的x.y坐标区分开来,WebGL使用s和t ...
- IT规划,是否一定要梳理流程
IT规划,是面向企业业务的 IT战略规划,必然需要考虑业务的运营特点和需求.以往为企业提供IT规划咨询服务时,很多企业都提出,IT规划要满足业务的需求,那就要对业务足够熟 悉,而通过梳理流程能够达到这 ...
- mysql中使用show variables同时查询多个参数值?show variables的使用?
需求描述: 今天在查mysq关于连接数的问题,想要通过一个show variables命令同时查出来多个值.在此记录下. 操作过程: 1.通过show variables语句的like可以匹配多个值或 ...