左移运算符重载
作用:可以输出自定义数据类型
1.利用成员函数实现左移运算符
classPerson {
public:
Person(inta, intb)
{
this->m_A=a;
this->m_B=b;
}
//利用成员函数实现左移运算符:p.operator<<(cout)简化版本p << cout 无法实现cout在左边。
//成员函数 p << p 不是我们想要的效果,想要cout<<p
voidoperator<<(Person&p){
cout<<"a:"<<p.m_A<<" b:"<<p.m_B;
}
private:
intm_A;
intm_B;
};
voidtest() {
Personp1(10, 20);
p1<<p1;//p1.operator<<(p1);
}
intmain() {
test();
system("pause");
return0;
}
上代码使用成员函数重载左移运算符的局限:成员函数 p << p 不是我们想要的效果,想要cout<<p
2.利用全局函数实现左移重载
classPerson {
//全局函数做友元,告诉编译器 operator<<全局函数 是 Person类的好朋友,可以访问类中的私有内容
friendvoidoperator<<(ostream&out, Person&p);
public:
Person(inta, intb)
{
this->m_A=a;
this->m_B=b;
}
private:
intm_A;
intm_B;
};
//只能全局函数实现左移重载
//ostream对象只能有一个
voidoperator<<(ostream&out, Person&p) {
out<<"a:"<<p.m_A<<" b:"<<p.m_B;
}
voidtest() {
Personp1(10, 20);
cout<<p1;
}
intmain() {
test();
system("pause");
return0;
}
上面的代码的局限性:输出结果无换行,若改为cout<<p<<endl;会报错,因为链式不成立,cout<<p是一个函数的调用,返回值是void,需要返回cout类型才能与endl;形成链式编程思想。
优化:
classPerson {
friendostream&operator<<(ostream&out, Person&p);
public:
Person(inta, intb)
{
this->m_A=a;
this->m_B=b;
}
private:
intm_A;
intm_B;
};
//只能全局函数实现左移重载
//ostream对象只能有一个,所以添加&取地址,cout的定义类型为ostream
ostream&operator<<(ostream&out, Person&p) {
out<<"a:"<<p.m_A<<" b:"<<p.m_B;
returnout;//返回cout需要更改函数头为ostream
}
voidtest() {
Personp1(10, 20);
cout<<p1<<"hello world"<<endl; //链式编程。
}
intmain() {
test();
system("pause");
return0;
}
PS:ostream& operator<<(ostream& out, Person& p){};
此处的Person& p
是否使用&对本程序没有影响,使用&指将p1传入,而不加&指拷贝构造一份p1后传入,不管是拷贝还是p1还是拷贝后的p1都打印的p1的内容。
总结:重载左移运算符配合友元可以实现输出自定义数据类型