简单版的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. Python——os(一)进程参数

    python的os模块提供了一种使用操作系统相关函数的通用手段,如果只是想读或写文件请移步 open(),向操作路径请查阅 os.path 模块,如果想要读取命令行中所有文件里的所有行请查阅 file ...

  2. Windows命令处理进程

    1.  查看进程命令 tasklist 2.以翻页模式查看进程 tasklist  |  more 3.搜索关键字查找进程 tasklist  |  findstr  "cmd" ...

  3. Yii2 session的使用方法(2)

    yii2打开session use yii\web\Session; $session = Yii::$app->session; // check if a session is alread ...

  4. unity3d 资源打包加密 整理

    资源打包脚本,放到Assets\Editor 文件夹下 using UnityEngine; using System.Collections; using UnityEditor; using Sy ...

  5. Java写 插入 选择 冒泡 快排

    /** * Created by wushuang on 2014/11/19. */ public class SortTest { @Test public void mainTest() { i ...

  6. rlwrap安装报错You need the GNU readline 解决方法

    首先大家肯定知道rlwrap是干什么的? 在linux以及unix中,sqlplus的上下左右.回退无法使用,会出现乱码情况.而rlwrap这个软件就是用来解决这个的.   这个错误曾经困扰我很久很久 ...

  7. jenkins 忘记admin用户账号密码

    一不小心,忘记了admin用户的账号密码.然后就看不到manage jenkins的那部分内容了,看不到就改不了用户权限,也就是系统瘫痪了. 于是,想着开始没注册账号和密码的时候,都能看见,也就是没有 ...

  8. NSIS 资料

    官方 http://nsis.sourceforge.net/Main_Page NSIS官方插件全集 http://az.eliang.com/aq_2013041703.html NSIS 衿华客 ...

  9. python中注释的写法

    说明: 记录在python中注释的写法. 1.单行注释,代码行以 # 开头 # 这是一个单行注释 print('hello world') 2.多行注释,使用三个单引号,或者三个双引号将其要注释的内容 ...

  10. 缓存管理(本地缓存+memcached)

    http://www.cnblogs.com/daizhj/archive/2009/11/17/1604436.html