C++运算符重载(二)之左移运算符重载

276 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

左移运算符重载

作用:可以输出自定义数据类型

1.利用成员函数实现左移运算符

class Person {
​
public:
​
    Person(int a, int b)
    {
        this->m_A = a;
        this->m_B = b;
    }
    //利用成员函数实现左移运算符:p.operator<<(cout)简化版本p << cout 无法实现cout在左边。
    //成员函数 p << p 不是我们想要的效果,想要cout<<p
    void operator<<(Person& p){
        cout << "a:" << p.m_A << " b:" << p.m_B;
    }
​
private:
    int m_A;
    int m_B;
};
​
void test() {
​
    Person p1(10, 20);
    p1 << p1;//p1.operator<<(p1);
}
​
int main() {
​
    test();
​
    system("pause");
​
    return 0;
}

上代码使用成员函数重载左移运算符的局限:成员函数 p << p 不是我们想要的效果,想要cout<<p

image-20220806181138331

2.利用全局函数实现左移重载

class Person {
    //全局函数做友元,告诉编译器 operator<<全局函数 是 Person类的好朋友,可以访问类中的私有内容
    friend void operator<<(ostream& out, Person& p);
​
public:
​
    Person(int a, int b)
    {
        this->m_A = a;
        this->m_B = b;
    }
​
private:
    int m_A;
    int m_B;
};
​
//只能全局函数实现左移重载
//ostream对象只能有一个
void operator<<(ostream& out, Person& p) {
    out << "a:" << p.m_A << " b:" << p.m_B;
}
​
void test() {
​
    Person p1(10, 20);
    cout << p1;
}
​
int main() {
​
    test();
​
    system("pause");
​
    return 0;
}

上面的代码的局限性:输出结果无换行,若改为cout<<p<<endl;会报错,因为链式不成立,cout<<p是一个函数的调用,返回值是void,需要返回cout类型才能与endl;形成链式编程思想。

优化:

class Person {
    friend ostream& operator<<(ostream& out, Person& p);
​
public:
​
    Person(int a, int b)
    {
        this->m_A = a;
        this->m_B = b;
    }
private:
    int m_A;
    int m_B;
};
​
//只能全局函数实现左移重载
//ostream对象只能有一个,所以添加&取地址,cout的定义类型为ostream
ostream& operator<<(ostream& out, Person& p) {
    out << "a:" << p.m_A << " b:" << p.m_B;
    return out;//返回cout需要更改函数头为ostream
}
​
void test() {
​
    Person p1(10, 20);
​
    cout << p1 << "hello world" << endl; //链式编程。
}
​
int main() {
​
    test();
​
    system("pause");
​
    return 0;
}

PS:ostream& operator<<(ostream& out, Person& p){};此处的Person& p是否使用&对本程序没有影响,使用&指将p1传入,而不加&指拷贝构造一份p1后传入,不管是拷贝还是p1还是拷贝后的p1都打印的p1的内容。

总结:重载左移运算符配合友元可以实现输出自定义数据类型