关于 操作符“<<”和“>>”重载的心得

       今天被操作符“<<”和“>>”的重载问题给纠缠一天,终于给搞懂了些。这一天的成果如果不来总结总结真的是对不起我的时间了。

       今天突然想自己实现下标准库 string 的部分功能,如构造,析构,输入,输出等。定义的类名为MyString。在实现“<<”操作符的重载时,遇到了很多问题让我,如下:

(1)在未查资料的情况下,部分代码如下:

//file name: MyString.h
#include <iostream>
using std::cout;
using std::endl;

class MyString {
private:
	char *str;
public:
	MyString &operator <<(MyString s);
};
//file name: MyString.cpp
#include "MyString.h"

MyString& MyString::operator<< (MyString s)
{
	cout<<s.str;
	return *this;
}
//file name: MainTest.cpp
#include "MyString.h"

int main(int argc, const char* argv[])
{
	MyString ms1= "hello world";
	cout<<ms1;<span style="white-space:pre">		</span>//这句显示错误<span style="color: rgb(255, 0, 0); "><strong>
</strong></span>	return 0;
}

结果出现错误:
error C2679: binary '<<' : no operator defined which takes a right-hand operand of type 'class MyString' (or there is no acceptable conversion)

出现错误的语句在上面标红的句子上。想不明白原因,于是查了资料:有的说没有引入 iostream ; 有的说要 operator<< 函数参数要加上 & 符号,即:MyString& operator<< (MyString &s)。 于是都照做了。结果:失败!还是error C2679。先说下自己困惑的地方:

在这里 operator<< 是类 MyString 的成员函数,而cout<<ms1 中调用这应该是 cout ,这明显不对。如果不用 cout 输出那要怎样输出了。于是乎,既然是类MyString 的成员函数,那就让ms1调用,然后传入又把参数ms1传入(这样写的话,明显是垃圾代码)。出乎意料的是,修改后竟然不报错了。

修改后语句1:

ms1<<ms1;

运行程序

修改后语句2:

ms1<<ms1<<endl;	//ms1<<ms1<<"\n"; 不报错

结果又出现了同样的错误。这完全不符合自己想要的结果,显然这样重载肯定是有问题的。于是继续查资料。。。

。。。。。

发现,说"<<"的重载一般都用友元函数来重载,原因是前面所说的,调用者是cout,cout不是 MyString 的对象,无法调用其成员函数。这下好了,这样只要把成员函数改为友元函数就行了。于是修改代码:

//file name: MyString.h

friend std::ofstream& operator<< (std::ofstream &os, const MyString &s);<span style="white-space:pre">	</span>//注意ofstream
//file name: MyString.cpp

std::ofstream& operator<< (std::ofstream &os, const MyString &s)
{
	cout<<s.str;
	return os;
}
// file name: MainTest.cpp

#include "MyString.h"

int main(int argc, const char* argv[])
{
	MyString ms1= "hello world";
	cout<<ms1<<endl;
	return 0;
}

结果:编译错误!!!

还是error C2679: binary '<<' : no operator defined which takes a right-hand operand of type 'class MyString' (or there is no acceptable conversion)

我崩溃了。。。检查代码好久好久,竟然坑爹的发现自己犯了低级错误,把 ostream 写成了 ofstream。 于是把代码替换了。

结果:成功了!!!

 

下面进行重要的小结哈。。。。

1. 重要的一点, error C2679: binary '<<' :...,并不是网上有的说的加入头文件 iostream 或是 参数加 & 符号就一定能解决的。这个错误是告诉我们 "<<" 操作符无法操作类 MyString 的对象。这说明什么? 说明上面两种情况都没有成功的对 "<<" 进行重载(第一种情况勉强可以吧,虽然觉得是没用的代码)。So, 以后遇到这错误,应该能很快的发现错误根源了。C2679我记住你了。

2. 既然用了友元函数,operator<<可以看做是函数名,cout<<ms1; 是把cout当做参数1,ms1作为参数2传给了 operator<< 函数,那就可以显示的调用 operator<<函数,如:operator<<(cout, ms1);

3. 要可以连续输出,则返回类型就应该为 std::ostream&

 

以上是今天的小小收获,能力有限,有错的地方希望大家指出哈。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值