C++ 为什么我们不能使用友元函数重载“=”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2865036/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't we overload "=" using friend function?
提问by Ashish
Why it is not allowed to overload "=" using friend function? I have written a small program but it is giving error.
为什么不允许使用友元函数重载“=”?我写了一个小程序,但它给出了错误。
class comp
{
int real;
int imaginary;
public:
comp(){real=0; imaginary=0;}
void show(){cout << "Real="<<real<<" Imaginary="<<imaginary<<endl;}
void set(int i,int j){real=i;imaginary=j;}
friend comp operator=(comp &op1,const comp &op2);
};
comp operator=(comp &op1,const comp &op2)
{
op1.imaginary=op2.imaginary;
op1.real=op2.real;
return op1;
}
int main()
{
comp a,b;
a.set(10,20);
b=a;
b.show();
return 0;
}
The compilation gives the following error :-
编译给出以下错误:-
[root@dogmatix stackoverflow]# g++ prog4.cpp
prog4.cpp:11: error: a?comp operator=(comp&, const comp&)a? must be a nonstatic member function
prog4.cpp:14: error: a?comp operator=(comp&, const comp&)a? must be a nonstatic member function
prog4.cpp: In function a?int main()a?:
prog4.cpp:25: error: ambiguous overload for a?operator=a? in a?b = aa?
prog4.cpp:4: note: candidates are: comp& comp::operator=(const comp&)
prog4.cpp:14: note: comp operator=(comp&, const comp&)
采纳答案by David Rodríguez - dribeas
The assignment operator is explicitly required to be a class member operator. That is a sufficient reason for the compiler to fail to compile your code. Assignment is one of the special member functions defined in the standard (like the copy constructor) that will be generated by the compiler if you do not provide your own.
赋值运算符明确要求是类成员运算符。这是编译器无法编译您的代码的充分理由。赋值是标准中定义的特殊成员函数之一(如复制构造函数),如果您不提供自己的,它将由编译器生成。
Unlike other operations that can be understood as external to the left hand side operator, the assignment is an operation that is semantically bound to the left hand side: modify this instance to beequal to the right hand side instance(by some definition of equal), so it makes sense to have it as an operation of the class and not an external operation. On the other hand, other operators as addition are not bound to a particular instance: is a+b
an operation of a
or b
or none of them? -- a
and b
are used in the operation, but the operation actson the resultvalue that is returned.
与可以理解为左侧运算符外部的其他操作不同,赋值是一种在语义上绑定到左侧的操作:修改此实例使其等于右侧实例(根据equal的某些定义) ,因此将其作为类的操作而不是外部操作是有意义的。另一方面,作为加法的其他运算符不绑定到特定实例:是它们a+b
的操作a
还是b
它们中的一个?--a
并b
在操作中使用,但操作作用于返回的结果值。
That approach is actually recommended and used: define operator+=
(that applies to the instance) as a member function, and then implement operator+
as a free function that operates on the result:
实际上推荐和使用这种方法:将operator+=
(适用于实例)定义为成员函数,然后operator+
作为对结果进行操作的自由函数来实现:
struct example {
example& operator+=( const example& rhs );
};
example operator+( const example& lhs, const example& rhs ) {
example ret( lhs );
ret += rhs;
return ret;
}
// usually implemented as:
// example operator+( example lhs, const example& rhs ) {
// return lhs += rhs; // note that lhs is actually a copy, not the real lhs
//}
回答by Michael Krelin - hacker
Because if you do not declare it as a class member compiler will make one up for you and it will introduce ambiguity.
因为如果您不将其声明为类成员,编译器将为您弥补,并且会引入歧义。
回答by Prof. D. H. Ingole
Assignment(=) operator is a special operator that will be provided by the constructor to the class when programmer has not provided(overloaded) as member of the class.(like copy constructor).
When programmer is overloading = operator using friend function, two = operations will exists:
1) compiler is providing = operator
2) programmer is providing(overloading) = operator by friend function.
Then simply ambiguity will be created and compiler will gives error. Its compilation error.
赋值(=)运算符是一种特殊的运算符,当程序员没有提供(重载)作为类的成员(如复制构造函数)时,它将由构造函数提供给类。
当程序员使用友元函数重载= 操作符时,将存在两个= 操作:
1)编译器提供= 操作符
2)程序员通过友元函数提供(重载)= 操作符。
然后会产生简单的歧义,编译器会给出错误。它的编译错误。
回答by alfC
There is no good reason for that, I think Stepanov proposed that there should be a free operator=
and many good stuff can be done with that (even more than what can be done with the move assignment). I can't find the citation but Stepanov went as a far as to suggest that the constructors could be free functions http://www.stlport.org/resources/StepanovUSA.html.
没有充分的理由,我认为 Stepanov 建议应该有一个免费的,operator=
并且可以用它来做很多好东西(甚至比移动分配可以做的更多)。我找不到引文,但 Stepanov 甚至建议构造函数可以是免费函数http://www.stlport.org/resources/StepanovUSA.html。
There is a way around it, which is to systematically declarea template<class Other> A& operator=(Other const& t);
in inside all your classes, in this way you leave the option to anyone to define a custom assignment operator.
有一种方法可以解决它,即在所有类中系统地声明a template<class Other> A& operator=(Other const& t);
in ,这样您就可以将选项留给任何人来定义自定义赋值运算符。
Of course you can't do this with a class you don't have control over.
当然,你不能用你无法控制的类来做到这一点。
Having said that it is nowadays not thatbad since we have move assignment. And in some sense conversion operators B::operator A() const{...}
are almost like a custom copy assignment. Conversion operators are now usable because of explicit
. However you have to have control over the second type (B
), the right-hand type in assignment.
话虽如此,因为我们有移动任务,所以现在还不错。从某种意义上说,转换运算符B::operator A() const{...}
几乎就像一个自定义的复制赋值。由于explicit
. 但是,您必须控制第二种类型 ( B
),即赋值中的右侧类型。
Next question is why conversion operator need to be members them selves? Again, I don't think there is a good reason.
下一个问题是为什么转换运算符需要自己成为成员?再说一次,我认为没有充分的理由。