重载 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= 作为非成员 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
为什么operator<<;;运算符重载一定要为友元函数呢?