简单版的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. windows server 安装phpVirtualBox web服务

    这是我在Windows server 2012 下的安装过程 (1) 安装virtualbox (2) 安装IIS和PHP, 参考: https://msdn.microsoft.com/zh-cn/ ...

  2. 每天一个linux命令: /etc/group文件详解

    Linux /etc/group文件与/etc/passwd和/etc/shadow文件都是有关于系统管理员对用户和用户组管理时相关的文件.linux /etc/group文件是有关于系统管理员对用户 ...

  3. 周期性调度器scheduler_tick

    周期性调度器由中断实现,系统定时产生一个中断,然后启动周期性调度器,周期性调度器执行过程中要关闭中断, 周期性调度器执行完毕后再打开中断(handle_IRQ_event,  IRQF_DISABLE ...

  4. git恢复删除的分支及内容

    git 删除分支git branch -D 分支名 git查看分支 git branch -a git 删除远程分支 git push origin :分支名 这里注意:git分支提交并且push了, ...

  5. web front end stack web 前段技术概览

    https://github.com/unruledboy/WebFrontEndStack

  6. webpack流程图

  7. js读取csv文件为json显示

    摘要: 前面分享了用js将json数据下载为csv文件,方便后期管理.但是对于测试人员更希望能够以页面的形式展现任务,所以就做了一个将csv文件展现在页面上的例子. 代码: <!DOCTYPE ...

  8. Android零碎知识点 1

    Android零碎知识点 1   Android在2.3版本上开始支持KeyEvent.KEYCODE_PAGE_DOWN以及KeyEvent.KEYCODE_PAGE_UP的操作.   Androi ...

  9. 假设数组a有n个元素,元素取值范围是1~n,如何判定数组是否存在重复元素

    方法一:位图法,原理是首先申请一个长度为n且均为’0’组成的字符串,字符串的下标即为数组a[]中的元素,然后从头开始遍历数组a[N],取每个数组元素的值,将其对应的字符串中的对应位置置1,如果已经置过 ...

  10. PHP+Oracle Instant Client

    <?php <b>●Oracleとの接続テスト</b> <hr> <?php // Oracleとの接続 $conn = OCILogon(" ...