代码之家  ›  专栏  ›  技术社区  ›  Chubsdad

运算符重载

  •  8
  • Chubsdad  · 技术社区  · 14 年前

    为什么重载运算符=必须是成员函数($13.5.3),而不是复合赋值运算符,例如运算符+=($13.5.2)?我是不是忽略了什么?

    4 回复  |  直到 14 年前
        1
  •  4
  •   CB Bailey    14 年前

    复印件转让 operator= ,作为成员,如果用户未定义,则始终由编译器提供。我相信这只是为了简单和避免意想不到的歧义,这是一个要求。 运算符= 不能定义为一个自由函数。

    当您要从用户定义的类型分配给内置类型时,转换运算符会处理这种情况。

        2
  •  2
  •   Motti    14 年前

    您所引用的部分说明了如何隐藏 operator=

    因为拷贝分配运算符 运算符= 如果用户没有声明(12.8),则为类隐式声明,

    这也可能是您问题的答案,因为编译器需要知道它是否应该生成 运算符= 它必须知道是否定义了这样的操作符,如果它可以在类之外定义,编译器就不能知道它是否被定义在不同的翻译单元中。

    例如

    //a.h
    class A { }; // compiler thinks A::operator= should be implicitly defined
    
    //b.h
    #include "a.h"
    A& operator=(A& This, const A& other) { /*...*/ } // Oops it's explicitly defined
    

    另一方面,复合运算符没有隐式定义,因此没有理由强制将其声明为成员函数。

        3
  •  1
  •   buc    14 年前

    与默认和复制构造函数一起,运算符=在C++中也被特别处理。这意味着,即使您没有声明一个,编译器也将为您提供一个默认实现。但是默认实现并不总是适合类的需要的行为,这就是为什么您应该显式地声明它们(或者通过分配私有可见性来隐藏它们)。

    为什么默认构造函数、复制构造函数和赋值运算符如此特殊?因为它们涉及到标准变量初始化和参数传递:当您通过值(而不是通过引用或指针)将类类型的参数传递给函数时,将调用这些操作来将其内容复制到堆栈中。

        4
  •  1
  •   icecrime    14 年前

    如查尔斯所述,一份复印件 operator= 如果用户未定义,则始终由编译器提供。此编译器提供的成员函数始终优先于非成员函数,因此即使您 能够 将其定义为非成员函数,则不会调用它。