【问题标题】:Overloading operators '=' and '+'重载运算符 '=' 和 '+'
【发布时间】:2017-04-07 20:07:16
【问题描述】:

我正在学习如何使用模板以及如何重载运算符。我已经设法重载operator[],但我遇到了重载operator+operator= 的问题。这是我的代码:

template <class T>
class A
{  
public:
    //...
    friend A<T>& A<T>::operator+ (A<T>&, const A<T>&);
    friend A<T>& A<T>::operator= (A<T>&, const A<T>&);
};

template<class T> A<T>& A<T>::operator+ (A<T>& left, const A<T>& right)
{
    //some functions
return left;
}

template<class T> A<T>& A<T>::operator= (A<T>& left, const A<T>& right)
{
    //some functions
    return left;
}

每当我尝试编译时,我都会收到这些错误:

'+': 不是'A'的成员

'=':不是'A'的成员

'operator =' 必须是非静态成员

我做错了什么?


编辑:

我已经设法更新了代码:

template <class T>
class A
{  
public:
    //...
    A<T> operator+ (A<T>);
    A<T> operator= (A<T>, const A<T>);
};

template<class T> A<T> A<T>::operator+ (A<T> right)
{
    //some functions
    return *this;
}

template<class T> A<T> operator= (A<T> right)
{
    //some functions
    return *this;
}

看起来operator+ 现在可以正常工作了,但是编译器给出了这个错误:

'operator=' 必须是非静态成员

为什么它是静态成员,我该如何修复它?

【问题讨论】:

  • 删除函数定义中的A&lt;T&gt;::范围。
  • 对不起,我忘了。模板参数不是 “继承”friend 声明。您必须将它们声明为template&lt;typename U&gt; friend A&lt;U&gt;&amp; operator+ (A&lt;U&gt;&amp;, const A&lt;U&gt;&amp;);
  • 你确定吗?我现在得到编译器的内部错误:P 没关系,它现在仍然产生“非成员”错误:/
  • 可以先放friend,但我对此有100%的把握。

标签: c++ operators overloading


【解决方案1】:

对于初学者,赋值运算符必须是非静态成员函数

来自 C++ 标准(13.5.3 赋值)

1 赋值运算符应由非静态成员实现 函数只有一个参数。因为复制作业 operator operator= 如果未声明,则为类隐式声明 由用户(12.8),基类赋值运算符始终隐藏 通过派生类的复制赋值运算符。

其次(11.3 个好友)

1 类的朋友是被授予权限的函数或类 使用类中的私有和受保护成员名称。一类 通过友元声明指定其友元(如果有)。这样的 声明赋予朋友特殊的访问权限,但他们这样做 不要让提名的朋友成为交友班的成员

例如这个定义

template<class T> A<T>& A<T>::operator+ (A<T>& left, const A<T>& right)
                        ^^^^^
{
//some functions
return left;
}

不正确。至少您应该删除A&lt;T&gt;::,因为该运算符不是该类的成员。

【讨论】:

  • 是的,我完全忘记了。所以现在我删除了朋友和 'A::' 但我仍然收到最后一个错误,operator= 必须是非静态成员。我怎样才能使它成为非静态的?实际上,我查看了我的 operator[] 定义,也出现了同样的错误,但由于某种原因,编译器让我这样做:P 现在它也产生了这个“非静态成员”错误:C
  • @Executor1909 再读一篇来自标准的引文。操作员应该只有一个参数。
  • 是的,我知道,但我改变了它只是为了检查那些以前的错误是否会消失,现在它们只有一个参数。 '非静态'错误仍然发生
  • @Executor1909 什么不清楚?运算符应在类定义中声明,并且没有朋友说明符。有什么问题?
  • 存在编译器错误,提示操作符 '=' 必须是非静态成员。声明现在看起来像这样: A operator= (const A&);和定义: template A operator= (const A& right) { //一些函数返回 *this;我不知道为什么它仍然是一个静态成员。
【解决方案2】:

作为非静态成员实现的运算符必须仅接受 1 个输入参数,即右侧操作数。左侧的操作数是调用该运算符的 this 对象。

作为静态成员或非成员实现的运算符必须接受 2 个输入参数,即左侧和右侧操作数。

您的 operator= 被声明为具有 2 个输入参数的非静态成员,这是错误的。

此外,operator+ 旨在返回一个新对象,该对象是添加在一起的两个输入对象的副本。不要返回对正在调用运算符的对象的引用。而operator= 旨在返回对分配给的对象的引用。

试试这个:

template <class T>
class A
{  
public:
    //...
    A<T> operator+(const A<T>&) const;
    A<T>& operator=(const A<T>&);
};

template<class T> A<T> A<T>::operator+(const A<T>& right) const
{
    A<T> result(*this);
    //some functions to add right to result as needed...
    return result;
}

template<class T> A<T>& A<T>::operator=(const A<T>& right)
{
    // some functions to copy right into this...
    return *this;
}

【讨论】:

    猜你喜欢
    • 2016-02-19
    • 2012-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多