前序代码
首先引入相关的标准库和命名空间。
#include <iostream>
#include <string>
using namespace std;
定义类
本示例定义一个Student类进行示范,类中含有三个成员变量和getter方法来获取变量的值。
class Student{
private:
string name;
int age;
double score;
public:
string getName(){
return this->name;
}
int getAge(){
return this->age;
}
double getScore(){
return this->score;
}
};
添加构造函数
在类中添加以下公有方法,分别构造全成员变量参数构造方法和空参构造方法,便于后面进行示范操作。
Student(string name,int age,double score){
this->name=name;
this->age=age;
this->score=score;
}
Student(){}
输出重载
正确示例1
以下代码对输出流运算符<<进行重载,输入输出流对象的引用和一个需要输出的对象,这里是Student,用cout在重载函数内直接进行输出,返回时返回输出流对象的引用(即返回传入的输出流本身)。
ostream & operator << (ostream &o,Student student){
cout<<student.name<<"\t"<<student.age<<"\t"<<student.score<<endl;
return o;
}
正确示例2
与示例1唯一的改动是将cout(实际上是std::cout)改为o,即传入的输入流对象的引用。此时是使用传入的输出流进行输出,而不是使用标准输出流,在示例1中共有两个不同的输出流,而这里只有一个。
ostream & operator << (ostream &o,Student student){
o<<student.name<<"\t"<<student.age<<"\t"<<student.score<<endl;
return o;
}
错误示例1
对传入对象未加引用,这种方法会产生以下的报错,是不允许的。
ostream & operator << (ostream o,Student student){
o<<student.name<<"\t"<<student.age<<"\t"<<student.score<<endl;
return o;
}
/tmp/MVBvZp3nGf.cpp: In function 'std::ostream& operator<<(std::ostream, Student)':
/tmp/MVBvZp3nGf.cpp:39:12: warning: reference to local variable 'o' returned [-Wreturn-local-addr]
39 | return o;
| ^
/tmp/MVBvZp3nGf.cpp:37:32: note: declared here
37 | ostream & operator << (ostream o,Student student){
| ~~~~~~~~^
ERROR!
/tmp/MVBvZp3nGf.cpp: In function 'int main()':
/tmp/MVBvZp3nGf.cpp:53:11: error: use of deleted function 'std::basic_ostream<_CharT, _Traits>::basic_ostream(const std::basic_ostream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'
53 | cout<<student;
| ^~~~~~~
In file included from /usr/local/include/c++/12.2.0/iostream:39,
from /tmp/MVBvZp3nGf.cpp:1:
/usr/local/include/c++/12.2.0/ostream:391:7: note: declared here
391 | basic_ostream(const basic_ostream&) = delete;
| ^~~~~~~~~~~~~
/tmp/MVBvZp3nGf.cpp:37:32: note: initializing argument 1 of 'std::ostream& operator<<(std::ostream, Student)'
37 | ostream & operator << (ostream o,Student student){
| ~~~~~~~~^
=== Code Exited With Errors ===
输入重载
正确示例
与输出流类似,这里由于是标准输入,所以改为cin也是可以的,但更推荐以下的写法。
istream & operator >> (istream &in,Student &student){
in>>student.name>>student.age>>student.score;
return in;
}
错误示例
这个错误较容易发生,需要着重注意,即传入对象未加引用,此时是传入对象的值,而非其实际对象,会导致构造新的对象,希望输入的内容就是无效的。
istream & operator >> (istream &in,Student student){
in>>student.name>>student.age>>student.score;
return in;
}
友元函数
由于变量本身是私有的,如果想直接获取其私有变量,即为保证上述代码正确运行,需要添加为友元函数在类中。
需要注意:此处的函数头要与重载函数保持一致。
friend ostream & operator << (ostream &o,Student student);
friend istream & operator >> (istream &in,Student &student);
索引重载
在类中添加此函数对索引符号进行重载,可以根据索引输出对应的内容。
需要注意,此处不需要添加friend关键字,也不需要传入对象,因为本身在对象内部,有this指针进行控制。
string operator [] (int i){
if(i==0){
return this->name;
}else if(i==1){
return to_string(this->age);
}else if(i==2){
return to_string(this->score);
}else throw "IllegalPositionException";
}
main函数示范
int main(void){
Student student;
cin>>student;
cout<<student;
cout<<student[0];
return 0;
}
结果示范如下:
/tmp/twL4OeKKG4.o
Zhang 16 98.5
Zhang 16 98.5
Zhang=== Code Execution Successful ===