当类是子类时重载赋值运算符

7
如何使用赋值运算符实现设置基类成员?例如,如果某人在派生类中定义赋值运算符,像这样:
(其中colourColour()都是基类的成员 - 这意味着下面指示的行是非法的)
Derived& Derived::operator=(const Derived& rhs) 
{
if (&rhs != this)
{

    Colour(rhs.colour);    // not allowed
        Colour(rhs.Colour());  // not allowed
}
return *this;
}

有什么解决方案吗? 在基类中是否有将运算符重载链接在一起的方法? 我应该像这样做...

有解决方案吗?在基类中是否有将运算符重载链接在一起的方法?我需要做些什么...
Derived& Derived::operator=(const Derived& rhs) : Base::operator=(rhs)
...?
4个回答

8
这是如何完成的:
class B
{
 public:
  B& operator=( const B & other )
  {
    v = other.v;
    return *this;
  }
  int v;
};

class D : public B
{
 public:
  D& operator=( const D & other )
  {
    B::operator=( other );
    return *this;
  }
};

4
你离成功很近了,只需将该调用放在方法体中即可。
 if (&rhs != this)
 {
    Base::operator=(rhs);
    // ...

2

您应该能够使用公共访问器和修改器:

Derived& Derived::operator=(const Derived& rhs) 
{
   if (&rhs != this)
      SetColour(rhs.GetColour());
   return *this;
}

否则,在基类中将成员保护起来,以便派生类可以访问:
Derived& Derived::operator=(const Derived& rhs) 
{
   if (&rhs != this)
      colour = rhs.colour;
   return *this;
}

第三种选择是在基类中定义一个公共的赋值运算符,并让派生类调用基类的运算符:
Derived& Derived::operator=(const Derived& rhs) 
{
   if (&rhs != this)
      Base::operator=(rhs);
   return *this;
}

以下是完整的测试用例:
#define TEST 2
class Base
{
public:
    Base() : m_protected(0), m_private(0) {}
    Base(int pro, int pri) : m_protected(pro), m_private(pri) {}
    ~Base() {}

#if TEST == 1
    Base& operator=(const Base& rhs)
    {
        if (this != &rhs)
        {
            m_protected = rhs.m_protected;
            m_private = rhs.m_private;
        }

        return *this;
    }
#elif TEST == 2
    void SetPrivate(int i) { m_private = i; }
    int GetPrivate() const { return m_private; }
#endif

protected:
    int m_protected;
private:
    int m_private;
};

class Derived : public Base
{
public:
    Derived() : Base() {}
    Derived(int pro, int pri) : Base(pro, pri) {}
#if TEST == 1
    Derived& operator=(const Derived& rhs)
    {
        Base::operator=(rhs);
        return *this;
    }
#elif TEST == 2
    Derived& operator=(const Derived& rhs)
    {
        if (this != &rhs)
        {
            SetPrivate(rhs.GetPrivate());
            m_protected = rhs.m_protected;
        }
        return *this;
    }
#endif
};

int main()
{
    Derived a;
    Derived b(10, 5);

    a = b;
        return 0;
}

你确定吗?我的编译器不允许我从基类中访问任何公共或其他的内容。 - Dollarslice
它说没有匹配的重载参数实例(这是不正确的),并且还说对象具有类型限定符,防止匹配。那是什么意思? - Dollarslice
如果您使用公共继承和非const方法,则所有这些都可以工作。您可以展示更多的类定义和用法吗? - AJG85
这只是非常标准的,全部都是公共的和非常量。 - Dollarslice
我更新了一个自包含的测试用例,可以让你尝试我之前提到的三种变化。 - AJG85

1

我在基类操作符中实现了operator=功能,用于分配/构造颜色。如果您想从派生类调用基类operator=,请使用以下方法:

Base::operator=(rhs)

在派生类的operator=()实现中,你提出的Derived operator=的签名据我所知不是有效的C++。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接