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) ...
随机推荐
- 创建自己的PKI公/私密钥对和公钥证书
1. 创建certificate request configuration file cert_req.conf******************************************* ...
- (实用)win7/8修改远程桌面连接默认端口
记录备忘. 在启用windows操作系统的远程连接时,使用默认的3389端口是一件比较危险的事情,通常我们将其改成一个比较独特的端口,使得目标系统不会直接将远程桌面连接的功能直接暴露在网络环境下. 步 ...
- firefox插件-HackBar介绍与试用
This toolbar will help you in testing sql injections, XSS holes and site security. It is NOT a tool ...
- LigerUI树节点选中之后节点背景太短
LigerUI树节点选中之后的效果如下: 可以看出,节点的背景太短,不能适应树的宽度 理想的效果应该是节点选中之后,节点背景和树的宽度一样 虽然没有找到官方的解决办法 但是,通过查询LigerUI的A ...
- Linux 定时任务crontab_014
1. crontab命令概念 crontab命令用于设置周期性被执行的指令.该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行. cron 系统调度进程. 可以使 ...
- asp.net mvc中配置路由默认值(Area中)
public class RouteConfig { ] { "Best.Site.Areas.BestPalace" }; public static void Register ...
- ORA-01033错误解决方案
现象:SQL*Plus无法连接,显示以下错误: ORA-01033 : ORACLE initialization or shutdown in progress 分析:应该是Oracle在启动后,用 ...
- Linux系统下wetty安装和使用说明
1. Wetty简介 Wetty是使用Node.js和websockets开发的一个开源Web-based SSH.关于Web-based SSH的更多资料请参考https://en.wikipedi ...
- Unity3D编辑器之重写Hierarchy的右键菜单
using UnityEngine; using UnityEditor; using System.Collections; public class MyHierarchyMenu { [Menu ...
- python获取数组中最多的元素
获取数组中数量最多的元素,也就是最频繁的那个元素,方法有很多,下面是3种最简单的: 用max函数 sample = [1,2,3,3,3,4,5,5] max(set(sample), key=sam ...