gpt4 book ai didi

c++ - 为什么非成员函数不能用于重载赋值运算符?

转载 作者:太空宇宙 更新时间:2023-11-04 13:50:17 26 4
gpt4 key购买 nike

可以使用成员函数重载赋值运算符,但不能使用非成员 friend 函数:

class Test
{
int a;
public:
Test(int x)
:a(x)
{}
friend Test& operator=(Test &obj1, Test &obj2);
};

Test& operator=(Test &obj1, Test &obj2)//Not implemented fully. just for test.
{
return obj1;
}

它导致了这个错误:

error C2801: 'operator =' must be a non-static member

为什么不能使用 friend 函数来重载赋值运算符?编译器允许使用 friend 重载其他运算符,例如 +=-=。支持 operator= 的内在问题/限制是什么?

最佳答案

首先,应该注意的是,这与运算符(operator)被具体实现为 friend 无关。它实际上是将复制赋值实现为成员函数或非成员(独立)函数。该独立函数是否会成为 friend 完全无关紧要:它可能是,也可能不是,取决于它想在类内部访问什么。

现在,这个问题的答案在 D&E 书 (The Design and Evolution of C++) 中给出。这样做的原因是编译器总是为类声明/定义成员复制赋值运算符(如果您不声明自己的成员复制赋值运算符)。

如果该语言还允许将复制赋值运算符声明为独立(非成员)函数,您最终可能会得到以下结果

// Class definition
class SomeClass {
// No copy-assignment operator declared here
// so the compiler declares its own implicitly
...
};

SomeClass a, b;

void foo() {
a = b;
// The code here will use the compiler-declared copy-assignment for `SomeClass`
// because it doesn't know anything about any other copy-assignment operators
}

// Your standalone assignment operator
SomeClass& operator =(SomeClass& lhs, const SomeClass& rhs);

void bar() {
a = b;
// The code here will use your standalone copy-assigment for `SomeClass`
// and not the compiler-declared one
}

如上例所示,复制赋值的语义会在翻译单元的中间发生变化——在声明独立运算符之前,使用编译器的版本。声明后使用您的版本。程序的行为将根据您放置独立复制赋值运算符声明的位置而改变。

这被认为是 Not Acceptable 危险(事实确实如此),因此 C++ 不允许将复制赋值运算符声明为独立函数。

的确,在您的特定示例中,碰巧专门使用了一个 friend 函数,运算符很早就在类定义中声明了(因为这是声明 friend 的方式)。因此,在您的情况下,编译器当然会立即知道您的运算符的存在。然而,从 C++ 语言的角度来看,一般问题与友元函数没有任何关系。从 C++ 语言的角度来看,它是关于成员函数与非成员函数的,非成员复制赋值的重载由于上述原因而被完全禁止。

关于c++ - 为什么非成员函数不能用于重载赋值运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23714125/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com