перегрузка операторов присваивания, когда класс является дочерним
как вы устанавливаете члены базового класса, используя реализацию оператора присваивания? Если, например, кто-то определяет оператор присваивания в производном классе такой:
(где как 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;
}