operator<< 类内实现的问题

//Student.h

class  Student
{
private:
int  mId;
float  height;
int  score;
public:
Student(int  id  =  0,  float  h  =  0,  int  s  =  0)  :height(h),  mId(id),  score(s)
{
}


ostream &operator<<(ostream &out, Student &s1){
    out << s1.mId << " " << s1.height << " " << s1.score << endl;
    return out;
}

//********************************

};

乍一看,没什么问题!
但是!
这时候cout 一个对象的时候编译会报错!
那问题出在哪呢???
后来
我将重载函数在类内改成了如下所示。前面加了一个friend

friend ostream &operator<<(ostream &out, Student &s1){
    out << s1.mId << " " << s1.height << " " << s1.score << endl;
    return out;
}

编译通过了!
此时能正常cout对象!
但奇怪的是,friend不是用于把非成员函数的声明为友元函数的吗?为什么直接在类内实现了呢?
难道不应该是这样吗?

class  Student
{
private:
int  mId;
float  height;
int  score;
public:
Student(int  id  =  0,  float  h  =  0,  int  s  =  0)  :height(h),  mId(id),  score(s)
{
}

friend ostream &operator<<(ostream &out, Student &s1);

};
ostream &operator<<(ostream &out, Student &s1){
    out << s1.mId << " " << s1.height << " " << s1.score << endl;
    return out;
}

注意,这种方法当然也可以。
但像之前的那种写法同样适用。
个人认为是ostream类是c++标准输出流的一个基类,是c++库中的类,
friend可能是把C++库中的ostream当成一个友元,相当于该类中friend友了一个C++库中的东西,并在类内实现了。
而如果不加friend,这个类内的ostream重载,程序并不认得,于是编译就会出问题。

此处追加一个很有意思的问题。

friend ostream &operator<<(ostream &out,const Student &s1){
    out << s1.mId << " " << s1.height << " " << s1.score << endl;
    return out;
}

为什么最好再Student &s1 前加一个const呢??
不加const行不行呢?
这里涉及到临时变量的问题
: 临时变量.、

再看下面一个例子

#include <iostream>
using namespace std;
class Point{
    public:
    Point(int a, int b):x(a),y(b){}
    Point operator=(const Point &p);
    ostream& operator<<(ostream &out);
    private:
    int x,y;
    
};
ostream& Point::operator<<(ostream &out)
{
    out << '(' << x << ',' << y << ')' << endl;
    return out;
}
Point Point::operator=(const Point &p){
    x = p.x;
    y = p.y;
    return Point(x,y);
}
int main(){
    Point a(1,2),b(3,4),c(5,6);
    a << cout; //居然编译成功,cout << a;编译失败!
    return 0;
}

a << cout; //居然编译成功,cout << a;编译失败!
为啥呢???
在类内的成员函数中,非静态成员函数参数隐藏着this参数,而且是第一个参数。
ostream& operator<<(ostream& out)
实际上是
ostream& operator<<(Point *this, ostream& out)
这样的。
我们都知道
运算符的重载实际上是函数重载。
​那么在调用该函数时,this 就默认传递了对象的地址。

在输出时,<<运算符要严格的按照参数的顺序进行书写,即先写this后写out。
所以是 a << cout;
​但我们希望是 cout << a;这样输出。
所以,通常重载的输出操作符是写在类外的,或者声明为友元函数,不会将其写为成员函数。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值