перегрузка операторов присваивания, когда класс является дочерним

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

(где как 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 ответов


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

 if (&rhs != this)
 {
    Base::operator=(rhs);
    // ...

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

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

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

Base::operator=(rhs)

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


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

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

третьим вариантом может быть определение оператора присваивания public в базовом классе и вызов производного класса базовым оператором:

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