C++运算符重载中容易发生的错误

前序代码

首先引入相关的标准库和命名空间。

#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 ===

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值