问题的引入:打印自定义类
众所周知,CPP中引入了std::cout函数,取代了C中的printf函数,让我们不用再写转义字符就可以实现控制台打印,真的十分方便的语法♪(´▽`)
int num=114541;
std::cout<<“hello world!”<<num<<std::endl;
string str="hello too";
std::cout<<str<<std::endl;
但是,cout却不能打印自定义类型
struct mstr
{
int tah;
}
int main()
{
mstr mstrexpm={114};
//cout<<mstrexpm<<endl;
//这是不可行的,编译器会报错
}
也许你这样写
void printmstr(mstr& mstrin)
{ cout<<mstin.tah<<endl;
}
但是这也太不优雅了(其实是作者想水一篇文章🕶️…)我们要知其一知其二(看看cout中发生了什么)
你cout的时候,发生了什么?(函数层面)
为什么,我们需要简单了解一下CPP中的流机制,在抽象层面,CPP把一切的输入输出都看成流(键盘输入,鼠标输入,屏幕显示,乃至网络输入输出)cout就是一个预定义的流对象 ,**<<**则是被重载的运算符,下面你写的代码
#include <iostream>
using namespace std;
int main()
{
cout<<"hello world"<<endl;
}
在编译器眼里,其实是这样的,本质是函数调用
(关于流,其实值得讲的东西很多,这里只是基本层面的理解, 关注博主,了解更多CPP知识)
#include <iostream>
using namespace std;
int main()
{
std::operator<<(std::cout, "hello world").operator<<(std::endl);
return 0;
}
那就是说明,CPP标准库里,其实已经写好内建类型和STD库对象的打印函数了,所以可以打印。那我要打印自己的类呢?
自己写一个函数不久行了?
下面以一个学生类为例
class Student {
public:
int age;
int id;
std::string name;
// 构造函数
Student(int a, int i, const std::string& n) : age(a), id(i), name(n) {}
};
// 自定义流输出操作符
std::ostream& operator<<(std::ostream& os, const Student& student) {
//返回值是std::ostream& 是输出流的引用,用于连续的输出
//std::ostream& os, const Student& student对应上面函数调用的参数
os << "Name: " << student.name << ", Age: " << student.age << ", ID: " << student.id;
//os是输出流对象,是下面需要返回的
return os;
}
int main() {
Student s(20, 12345, "Alice");
std::cout << s << std::endl;
return 0;
}
这样写是更优雅了吧(好像没啥区别)