重载 operator= 作为非成员 [重复]

Posted

技术标签:

【中文标题】重载 operator= 作为非成员 [重复]【英文标题】:Overloading operator= as Non-Member [duplicate] 【发布时间】:2011-07-19 20:01:22 【问题描述】:

根据this线程的回复,operator=不能作为非成员函数重载。因此,例如,以下内容会使编译器非常生气:

class MyClass

    // ...
;

MyClass& operator=(MyClass& Left, MyClass& Right)

    // ...

这是为什么?我有一个带有 getter 和 setter 的容器类,所以成员函数是不必要的,它会破坏封装。上述线程的一个答案是确保“将 L 值作为其第一个操作数接收”,但我不完全理解这意味着什么。有人可以澄清一下吗?

此外,还有operator=operator()operator[]operator-> 的“奇怪”案例...?或者我应该将 all 重载运算符实现为成员函数...? (我知道这样做是完全合法的,但我正在寻找更好的做法。)

【问题讨论】:

另见此帖***.com/questions/3938036/… 我认为 getter/setter 比赋值运算符更能打破封装。注意:如果你没有定义一个你的类已经有一个赋值运算符。试试看。 成员函数不会破坏封装;他们是其中的一部分。创建“非成员、非友元函数”的偏好可能会导致类更简单,但在一般情况下,公开实现 operator=() 所需的所有内容比让 operator=() 成为成员更有可能削弱封装。 在这里回答:***.com/questions/3933637/… 【参考方案1】:

如果您的类没有赋值运算符(作为成员),则编译器默认生成一个,就像如果您不提供它会生成一个复制构造函数一样。

因此,如果您稍后尝试定义非成员赋值运算符,它会“生气”。然后会有两个!

【讨论】:

可以简单地更改规则以尝试先找到非会员。 @GMan 如果非会员操作员在另一个翻译单元中怎么办?违反 ODR? @GMan:那么,您将如何制定不违反 ODR 的定义?您总是必须定义它是一些翻译单元。 @GMan (first comment) 当看到定义时,该规则将应用于类定义。 C++ 不喜欢一个类可以在同一个源文件的不同位置有两个不同的定义。 @Andrey @James:对不起,我删除了我的答案,忘记了 cmets。我不再支持我在这个问题中提出的任何主张。 :) 安德烈在上面链接的另一个问题中回答了这个问题。【参考方案2】:

这是为什么?

除非你声明一个,否则编译器会在你的类中声明一个operator=,签名为operator= (C&, C&)operator= (C&, const C&)

如果允许重载赋值,大多数用途都会是模棱两可的。

那么您可能会游说附加规则

假装没有编译器声明operator=,如果用户声明的编译器可见,就好像非成员operator=隐藏了成员operator= 在重载期间使您的用户声明分配更好地匹配。

这两种选择都会使已经非常复杂的规则变得复杂,为operator=添加一个特殊情况。

很少有人想去那里。

而且您还没有公开此功能的合法用途。

或者,任何合理使用。

只有在可以展示一些合理的用例时,C++ 规则才会变得更加复杂。

【讨论】:

以上是关于重载 operator= 作为非成员 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

重载运算符作为成员函数还是非成员函数

Part8 多态性 8.1运算符重载

为什么operator<<;;运算符重载一定要为友元函数呢?

C ++重载:[错误]'operator ='不匹配(操作数类型是'String'和'String')[重复]

运算符重载三种形式(成员函数,友元函数,普通函数)详解

使用非成员函数从输入流中提取类对象