作用:可以输出自定义数据类型
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
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的内容。
总结:重载左移运算符配合友元可以实现输出自定义数据类型