操作符重载:从成员函数调用友元函数

Operator overloading: calling friend function from member function

本文关键字:函数调用 友元 函数 成员 重载 操作符      更新时间:2023-10-16

我有一个学生类。我想重载+运算符,这样我就可以在类中添加一个双变量。这里是Student类:

class Student {
private:
    std::string firstName;
    double grade;
public:
    Student(const std::string &firstName, double grade);
    double getGrade() const;
    friend Student operator+(double grade, const Student &student);
    Student operator+(double grade) const;
}; 

和实现:

Student::Student(const std::string &firstName, double grade) {
    this->firstName = firstName;
    this->grade = grade;
}
double Student::getGrade() const {
    return grade;
}
Student operator+(double grade, const Student &student) {
    return Student(student.firstName, student.grade + grade);
}
Student Student::operator+(double grade) const {
    return operator+(grade, *this);
}

double + Student通过好友函数完成,Student + double通过成员函数完成。当我编译时,我得到这个:

error: no matching function for call to ‘Student::operator+(double&, const Student&) const’
     return operator+(grade, *this);
                                  ^
note: candidate is:
note: Student Student::operator+(double) const
 Student Student::operator+(double grade) const {
         ^
note:   candidate expects 1 argument, 2 provided

为什么不能从成员函数调用友元函数?

(更新)

然而,当我重载<<操作符时,我可以从成员函数中调用它,而不需要预先挂起::

friend std::ostream &operator<<(std::ostream &os, const Student &student);

和实现:

std::ostream &operator<<(std::ostream &os, const Student &student) {
    os << student.grade;
    return os;
}

您正在尝试调用成员函数,而不是好友函数(cfr)。c++ 11 7.3.1.2/3)。你应该写

Student Student::operator+(double grade) const {
    return ::operator+(grade, *this);
}

使用::确保重载解析从当前所在的全局命名空间发生。

另一种方法(我认为可读性较差)是将friend函数添加到重载解析集

Student Student::operator+(double grade) const {
    using ::operator+;
    return operator+(grade, *this);
}

或者,如Jarod建议的,更容易读懂,

Student Student::operator+(double grade) const {
    return grade + *this;
}

编辑:至于"为什么":[class.friend]/p7[basic.lookup.]Argdep]/p3解释重载解析时同名的成员函数"隐藏"了友元函数的名称。