“operator =必须是非静态成员”是什么意思?

时间:2009-05-15 23:33:14

标签: c++ class operator-overloading non-static

我正在创建一个双链表,并且已经重载了operator =使列表上的内容等于另一个:

template<class T>
void operator=(const list<T>& lst)
{
    clear();
    copy(lst);
    return;
}

但是当我尝试编译时出现此错误:

container_def.h(74) : error C2801: 'operator =' must be a non-static member

此外,如果有帮助,第74行是定义的最后一行,带有“}”。

4 个答案:

答案 0 :(得分:19)

正是如此:带有1个参数的运算符重载必须是成员函数。 (在课堂内宣布)

template<class T>
void list<T>::operator=(const list<T>& rhs)
{
    ...
}

此外,从L =返回LHS可能是一个好主意,因此你可以链接它(如a = b = c) - 所以 list<T>& list<T>::operator=....

答案 1 :(得分:18)

将该运算符放在类定义中。它必须是成员,因为operator=是特殊的,无论如何你都不会通过将其写成非成员来获得某些东西。非会员运营商有两个重要的主要好处:

  • 右侧对操作员调用左侧的隐式转换
  • 无需了解班级的内部成员。功能可以作为非会员非朋友实现。

对于operator=,两者都不可用。分配转换的临时结果没有意义,operator=在大多数情况下需要访问内部。此外,如果您不提供一个特殊的operator=,则由C ++自动提供(所谓的复制赋值运算符)。使operator=作为非成员重载成为可能会增加复杂性,显然没有实际收益,因此不允许这样做。

因此,请更改您的代码,使其看起来像这样(假设operator= 是一个复制赋值运算符,但是从list<T>分配给其他东西。你的问题并不清楚这一点:

class MyClass {
...
    template<class T>
    MyClass& operator=(const list<T>& lst)
    {
        clear();
        copy(lst);
        return *this;
    }
...
};

operator=再次返回对自身的引用是非常标准的。我建议你坚持这种做法。程序员看起来很熟悉,如果它会突然返回void,可能会引起意外。

答案 2 :(得分:6)

如果将运算符作为成员函数重载,则应使用此模板:

class A {
  A& operator=(const A& other) {
    if (this != &other) {
      ...
    }
    return *this;
  }
}

需要注意三点:

  1. 使用赋值运算符检查自我赋值(如上所述);
  2. 参数应该是const引用;和
  3. 将操作结果作为非const引用返回,返回* this以允许操作符链接。
  4. 您还可以重载类外部的操作符。这与此示例无关,因为您无法使用赋值运算符执行此操作,但值得注意,因为在许多情况下它优于成员函数。典型的形式是:

    class A {
      friend const A& operator+(const A& a, const A& b);
      ...
    }
    const A& operator+(const A& a, const A& b) {
      A& ret = ...
      return ret;
    }
    

    这个返回一个const引用,所以你不能这样做:

    (a + b) = c
    

答案 3 :(得分:-1)

来自C ++标准,“二元运算符”:

“二元运算符应由具有一个参数的非静态成员函数或具有两个参数的非成员函数实现”

它希望你在一个类中定义它,作为一个成员,或者使它成为一个静态方法(在这种情况下,它应该采用两个参数(对于lval和rval)。