简单版的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. 使用sphinx创建和查看文档

    1. 安装pip $ sudo apt-get install python-pip 2. 安装全文本浏览器lynx $ sudo apt-get install lynx 3. 使用pip安装sph ...

  2. Winform控件学习笔记【第二天】——常用控件

    背景:期末考试刚过就感冒了,嗓子火辣辣的,好难受.但是一想起要学习总结就打起精神来了,Winform控件网上也没有多少使用教程,大部分都是自己在网上零零散散的学的,大部分用的熟了,不总结会很容易忘得. ...

  3. Oracle 一个中文汉字 占用几个字节,由Oracle中字符集编码决定

    Oracle 一个中文汉字 占用几个字节,要根据Oracle中字符集编码决定 查看oracle server端字符集 select userenv('language') from dual; 如果显 ...

  4. git忽略已添加版本控制的文件

    今天使用git做maven项目的版本控制,刚开始搭建项目后,把所有文件全部提交了. 已经提交的文件,gitignore中后配置也无效了. 所以使用以下命令来操作,操作后要提交哦. 1.执行 git r ...

  5. Linux中Subversion配置实例

    一.安装 yum install subversion 二.配置 本系统采用为每个项目单独建一版本库的策略.配置文件,密码文件,访问控制文件等都放在版本库的conf目录下. 所以每次开始一个新项目都必 ...

  6. Scala2.11.8 spark2.3.1 mongodb connector 2.3.0

    import java.sql.DriverManager import com.mongodb.spark._ import org.apache.spark.SparkConf import or ...

  7. LinuxMint下的Orionode源码安装

    1. Orionode介绍 Eclipse-orion是Eclipse项目下面的一个子项目,orion是一个在在线版的代码编辑环境.其介绍参考http://wiki.eclipse.org/Orion ...

  8. Oracle统计每条数据的大小

    怎么查询一条记录到底占了多少空间呢,随便用一个表举例(如上图),就着解决眼前问题的原则(oracle),网上简单查了查,发现生效了,就没深入了解了,包括其它数据库怎么解决,都没做研究.Oracle下, ...

  9. vue加百度统计代码(亲测有效)

    申请百度统计后,会得到一段JS代码,需要插入到每个网页中去,在Vue.js项目首先想到的可能就是,把统计代码插入到index.html入口文件中,这样就全局插入,每个页面就都有了;这样做就涉及到一个问 ...

  10. python-反射、新式类与经典类搜索的优先级

    preface include: getattr setattr delattr hasattr class webserver(object): def __init__(self,num): se ...