C++ 重载相同操作的友元函数和类方法的优先级
这是我的密码:C++ 重载相同操作的友元函数和类方法的优先级,c++,methods,operator-overloading,overloading,friend,C++,Methods,Operator Overloading,Overloading,Friend,这是我的密码: #include <iostream> using namespace std; class RationalNumber { private: int num; int den; public: RationalNumber(int a):num(a),den(1){} RationalNumber(int a, int b):num(a),den(b){} void parse() { cou
#include <iostream>
using namespace std;
class RationalNumber
{
private:
int num;
int den;
public:
RationalNumber(int a):num(a),den(1){}
RationalNumber(int a, int b):num(a),den(b){}
void parse()
{
cout << num << "\\" << den << endl;
}
RationalNumber operator/(RationalNumber);
};
RationalNumber RationalNumber:: operator/(RationalNumber b)
{
return RationalNumber(num * b.den, den * b.num);
}
int main()
{
RationalNumber a(1,2);
int c = 5;
(a/c).parse();
return 0;
}
#包括
使用名称空间std;
类有理数
{
私人:
int-num;
int den;
公众:
有理数(inta):num(a),den(1){
有理数(inta,intb):num(a),den(b){
void parse()
{
cout我将提供一个简化视图。为此,您将扮演编译器的角色
假设您正忙于编译一些代码,遇到一个运算符,它被赋予了一个RationalNumber
和一个int
作为操作数。该怎么办?好吧,编译器的工作描述包括将运算符与实现相匹配,因此您会抱怨并查看声明列表。您会发现两个可行的选项
RationalNumber
的一个成员,它期望一个RationalNumber
作为它的第二个操作数。这不是一个完美的匹配,但是你可以找到你记得在某处看到的从int
到RationalNumber
的讨厌的转换
一种自由运算符,期望一个有理数
作为其第一个操作数,一个int
作为其第二个操作数。完美匹配
您正忙于编译代码。您确实不想找到这种转换,因此选择#2作为更简单的选项
事实并不像上面那样轻率,但基本原则是合理的。在编译一个参数列表后,编译器将在声明的参数和提供的参数之间寻找最佳匹配。不严格地说,“最佳”匹配是需要编译器进行最少工作的匹配。(有很多转换使其精确。)精确匹配(提供的参数已经是所需的类型)比其他类型更可取
在决策过程的这一点上,没有考虑“朋友”和“成员”之间的区别。我将提供一个简化的视图。为此,您将扮演编译器的角色
假设您正忙于编译一些代码,遇到一个运算符,它被赋予了一个RationalNumber
和一个int
作为操作数。该怎么办?好吧,编译器的工作描述包括将运算符与实现相匹配,因此您会抱怨并查看声明列表。您会发现两个可行的选项
RationalNumber
的一个成员,它期望一个RationalNumber
作为它的第二个操作数。这不是一个完美的匹配,但是你可以找到你记得在某处看到的从int
到RationalNumber
的讨厌的转换
一种自由运算符,期望一个有理数
作为其第一个操作数,一个int
作为其第二个操作数。完美匹配
您正忙于编译代码。您确实不想找到这种转换,因此选择#2作为更简单的选项
事实并不像上面那样轻率,但基本原则是合理的。在编译一个参数列表后,编译器将在声明的参数和提供的参数之间寻找最佳匹配。不严格地说,“最佳”匹配是需要编译器进行最少工作的匹配。(有很多转换使其精确。)精确匹配(提供的参数已经是所需的类型)比其他类型更可取
在决策过程的这一点上,“朋友”和“成员”之间的区别未查看。调用friend函数不需要隐式转换,因此选择它而不是member函数。对这个问题的完整回答需要很多篇幅。TLDR版本是,如果编译器可以调用函数而不转换任何参数,那么它宁愿这样做,而不是调用不转换参数的版本s需要一些转换。如果添加RationalNumber运算符/(int),请阅读
成员函数到理性数
,您应该得到的错误将表明友元函数或成员函数之间没有偏好。调用友元函数不需要隐式转换,因此选择它而不是成员函数。完整回答此问题需要很多页的密集文章。TLDR版本如果编译器可以在不转换任何参数的情况下调用函数,则它更愿意这样做,而不是调用确实需要一些转换的版本。如果添加RationalNumber运算符/(int),请阅读;
成员函数到理性编号
,您应该得到的错误将表明友元函数和成员函数之间没有偏好。
#include <iostream>
using namespace std;
class RationalNumber
{
private:
int num;
int den;
public:
RationalNumber(int a):num(a),den(1){}
RationalNumber(int a, int b):num(a),den(b){}
void parse()
{
cout << num << "\\" << den << endl;
}
RationalNumber operator/(RationalNumber);
friend RationalNumber operator/(RationalNumber, int);
};
RationalNumber RationalNumber:: operator/(RationalNumber b)
{
return RationalNumber(num * b.den, den * b.num);
}
RationalNumber operator/(RationalNumber v, int n )
{
return RationalNumber(0,0);
}
int main()
{
RationalNumber a(1,2);
int c = 5;
(a/c).parse();
return 0;
}