перегрузка операторов присваивания, когда класс является дочерним - PullRequest
6 голосов
/ 08 декабря 2011

Как вы устанавливаете членов базового класса, используя реализацию оператора присваивания?Например, если кто-то определяет оператор присваивания в производном классе следующим образом:

(где colour и Colour() являются членами базового класса - это означает, что указанные ниже строки недопустимы)

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 ]

6 голосов
/ 08 декабря 2011

Это делается так:

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 голосов
/ 08 декабря 2011

Вы близки, просто поместите этот вызов в тело метода.

 if (&rhs != this)
 {
    Base::operator=(rhs);
    // ...
1 голос
/ 08 декабря 2011

Я реализую оператор = функциональность назначения / конструирования цвета в операторе базового класса, если вы хотите вызвать базовый оператор = из использования в производном классе:

Base::operator=(rhs)

в реализации оператора производного класса = (). Насколько я знаю, подпись, которую вы предложили для оператора Derived =, недействительна для C ++.

1 голос
/ 08 декабря 2011

Вы должны иметь возможность использовать открытые методы доступа и мутаторы:

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;
}
...