目录
C++中一般使用 cout 来打印数据,但是可惜的是,cout 一般仅支持内置类型的打印,对于结构体/ 类 这种自定义类型的数据,cout 并不支持。
由于 cout 打印的本质其实是调用了 operator <<() 函数,因此,我们可以通过重载 operator <<() 函数来实现自定义类型的打印。
下面是 ostream类 中的operator<< 函数
流插入操作符<< 一般有两个操作数,这个函数因为是在ostream类内部声明的,所以隐藏了一个 this 指针,实际上声明应该是像下面这样:
ostream& operator<<(ostream& this, int val);
实际在调用 cout << val 的时候,会被转换成 operator<< (cout , val) 的形式。
operator<< 函数的返回值是ostream 对象的引用,目的是为了支持连续调用流插入函数。
- cout << a << b << endl;
- // (cout << a) << b <
- // operator<<(cout, a) << b << endl;
- // cout << b << endl;
operator<<(cout, a) 的返回值依然是 cout,只不过是已经将 变量 a 插入到标准输出流以后的 cout。此时的 cout 将作为下一个 << 操作符的 左操作数来使用。
假设我们要实现重载 自定义类Person 的operator << 函数。类的声明如下:
- class Person {
- public:
- Person(char* name, int age):_name(name),_age(age)
- {
- }
- private:
- char* _name;
- int _age;
- };
跟内置类型的一样,返回值是ostream& 类型,因为要支持连续流插入,值得注意的是,为了使用 ostream 类型,需要同时引入 iostream 头文件 以及 标准命名空间 std。
- #include
- using namespace std;
-
- ostream& operator<< (ostream& os, Person p);
operator << 函数的声明和定义是放在类外的,如果放在类内部,会自动加上一个隐藏的 this 指针,就i像下面这样:
ostream& operator<< (Person* this, ostream& os, Person p);
而且要在Person 类的内部声明 operator<<函数为友元函数,因为类外无法访问 private 成员。
- class Person {
- friend ostream& operator<< (ostream& os, Person p);
- public:
- Person(char* name, int age):_name(name),_age(age)
- {
- }
- private:
- char* _name;
- int _age;
- };
准备工作已经完成,最后就是实现了,完整的实现过程如下:
- class Person {
- friend ostream& operator<< (ostream& os, Person p);
- public:
- Person(char* name, int age):_name(name),_age(age)
- {
- }
- private:
- char* _name;
- int _age;
- };
-
- ostream& operator<< (ostream& os, Person p)
- {
- os << p._name << p._age << endl; // 将成员输入到流中,至于是什么流,这里可以先把os当作标准输出流
- return os;
- }
-
- int main() {
- char arr[20] = { "张三" };
- Person p1(arr, 18);
-
- cout << p1 << endl;
-
- return 0;
- }