简单版的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 类实现 以及>> <<流插入/流提取运算符重载的更多相关文章

  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. (实用)Ubuntu 开启NFS服务

    本文介绍如何在Ubuntu下开启NFS文件系统,从而挂载网络上其他机器的文件系统. NFS, Network File System, 即网络文件系统,通常NFS有提供者和使用者,提供者export自 ...

  2. SecureCRT同时发送命令到所有主机

    有时候我们需要在多台服务器上执行相同的命令,比如安装软件,复制,粘贴,删除等等,但一台一台的去操作工作量就太大了,我们可以借助SecureCRT这款客户端远程连接工具实现这样的要求! 相关阅读: 如何 ...

  3. Jenkins+Github配置【转】

    一.GitHub上配置 前提:Jenkins能正常打开 将本地文件上传到GitHub上:进入终端 cd Documents cd project git clone https://github.co ...

  4. Docker命令之 search

    docker search : 从Docker Hub查找镜像 语法 docker search [OPTIONS] TERM OPTIONS说明: --automated :只列出 automate ...

  5. iOS : 判断运行设备类型是否是iPad

    以下代码由 CocoaChina 版主 “cclv” 分享,可用于判断应用运行的设备是否是 iPad #define isPad (UI_USER_INTERFACE_IDIOM() == UIUse ...

  6. [转]Phantomjs实现获取网页快照并生成缩略图

    Shell脚本实现获取网页快照并生成缩略图 这篇文章主要介绍了Shell脚本实现获取网页快照并生成缩略图,本文获取网页快照使用phantomjs.生成缩略图使用ImageMagick,需要的朋友可以参 ...

  7. 【WP8】ScrollViewer滑动到底触发器(ListBox失效)

    很多时候会有到底加载更多的需求,而ScrollViewer不支持继承,无法继承它进行扩展,只能通过触发器来控制到底的事件(当然,可以通过UserControl去扩展) 思路:定义一个Trigger,自 ...

  8. VC++调用MSFlexGrid的SetRow方法,出现异常“Invalid Row Value”

    MSFlexGrid是微软提供的网格表格控件,SetRow方法用于设置当前焦点所在行.  C++ Code  12345   void CMSFlexGrid::SetRow(long nNewVal ...

  9. 利用ROS工具从bag文件中提取图片

    bag文件是ROS常用的数据存储格式,因此要从bag文件中提取数据就需要了解一点ROS的背景知识. 1. 什么是ROS及其优势 ROS全称Robot Operating System,是BSD-lic ...

  10. linux中高亮显示文本的工具 -- bat

    bat 的项目地址 https://github.com/sharkdp/bat bat 是用rust 开发的, 在centos中安装bat需要rust的环境, 我们可以通过安装rust的包管理工具c ...