我试图分析为什么一些运算符((),[], - >,=)应该仅作为成员函数重载。我失败了,我试图在互联网上搜索但没有用。任何人都可以帮我理解这个限制吗?
答案 0 :(得分:2)
某些形式的运算符需要访问类实例的“this”指针才能直接在该实例上运行,因为它们只将一个参数作为同一类型。
class A{
public:
int x;
// only takes a reference to another 'A' type, so we need the 'this' pointer
A& operator=(const A& other){
this->x = other.x;
return *this;
}
};
答案 1 :(得分:2)
虽然可能不太令人满意,但这是标准所说的:
(强调是我的)
§3.5.3作业
赋值运算符应由具有一个参数的非静态成员函数实现。
§3.5.4函数调用
operator()必须是具有任意数量参数的非静态成员函数。
§3.5.5订阅
operator []应该是非静态成员函数,只有一个参数。
§3.5.6班级成员访问
操作符 - >应该是一个不带参数的非静态成员函数。
我无法谈论这些要求背后的原因,因此我将把这方面留给那些更熟悉编译器设计的人。
答案 2 :(得分:1)
我认为这很可能是为什么标准的那部分是这样编写的。
但是如果不禁止,那么在我的测试代码中永远不会调用好友版本
Complex operator+(const Complex &other);
被定义为私有,编译器会 给出错误信息
‘Complex Complex::operator+(const Complex&)’ is private
Complex Complex::operator+(const Complex &other)
而不是使用好友版
参考Why cannot a non-member function be used for overloading the assignment operator?
因为编译器提供的默认运算符=(成员复制一个)总是优先。即你的朋友运营商=永远不会被召唤。
(如果赋值是在类方法中执行的,由于查找规则,成员函数(在这种情况下由编译器生成)将优先)
我尝试使用operator +进行测试。它证明了优先权
输出:
member function called
7+11i
测试代码:
#include<iostream>
using namespace std;
class Complex
{
public:
Complex(int real, int imag);
Complex(void);
~Complex(void);
Complex &Add(const Complex &other);
void Display() const;
Complex operator+(const Complex &other);
friend Complex operator+(const Complex &c1, const Complex &c2);
private:
int real_;
int imag_;
};
Complex::Complex(int real, int imag): imag_(imag), real_(real)
{
}
Complex::Complex(void)
{
}
Complex::~Complex(void)
{
}
Complex &Complex::Add(const Complex &other)
{
real_ += other.real_;
imag_ += other.imag_;
return *this;
}
void Complex::Display() const
{
cout << real_ << "+" << imag_ << "i" << endl;
}
Complex Complex::operator+(const Complex &other)
{
int r = real_ + other.real_;
int i = imag_ + other.imag_;
std::cout << "member function called"<< std::endl;
return Complex(r, i);
}
Complex operator+(const Complex &c1, const Complex &c2)
{
int r = c1.real_ + c2.real_;
int i = c1.imag_ + c2.imag_;
std::cout << "friend function called"<<std::endl;
return Complex(r, i);
}
int main(void)
{
Complex c1(3, 5);
Complex c2(4, 6);
Complex c3 = c1 + c2;
c3.Display();
return 0;
}