Оператор присваивания с аргументом производного типа - PullRequest
2 голосов
/ 09 сентября 2011
class A {
private:
    A& operator=(const A&);
};

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


int main() {

    B b1;
    B b2;

    b1 = b2;

    return 0;
}

Это дает ошибку при компиляции:

test.cpp: In member function 'B& B::operator=(const B&)':
test.cpp:16:5: error: 'A& A::operator=(const A&)' is private
test.cpp:19:20: error: within this context
test.cpp: In function 'int main()':
test.cpp:31:7: note: synthesized method 'B& B::operator=(const B&)'
first required here 
Build error occurred, build is stopped

Поскольку B :: operator = (A &) имеет нестандартную сигнатуру, компилятор генерирует свой собственный B :: operator = (B &)который (пытается) вызвать A :: operator (A &), который является приватным.

Есть ли способ заставить компилятор использовать B :: operator = (A &) также для аргументов B?

Ответы [ 3 ]

7 голосов
/ 09 сентября 2011

Конечно.Просто определите оператора самостоятельно и переадресуйте вызов на operator=(const A&).

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

    B& operator=(const B& other) {
        return *this = static_cast<const A&>(other);
    }
};
0 голосов
/ 09 сентября 2011

Я думаю, что не стоит пытаться использовать перегрузку операторов с унаследованными типами. В C ++ я рекомендую вам явно предоставлять функции для каждого поддерживаемого типа, когда речь идет о перегрузке операторов.

Я сам попал в эту ловушку не так давно. Если вы хотите узнать, как опытные c ++ люди используют эту функцию, я рекомендую вам изучить специализацию шаблонов std::vector<bool>.

.

Возможно, приведенный выше ответ может помочь вам решить эту проблему: C ++ Абстрактный вопрос перегрузки операторов класса и применения интерфейса

Другое возможное решение будет:

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

class A {
private:
  A& operator=(const A&);
public:
  operator B() { /* do stuff to convert from A to B */ }
};

int main() {

  B b1;
  B b2;

  b1 = b2;

  return 0;
}
0 голосов
/ 09 сентября 2011

Эта проблема связана с C ++, который я связываю с неприятным запахом при зачатии .

Ваша проблема, скорее всего, ложная проблема, и, кроме того, нет идеального решения.Старайтесь изо всех сил, в реализованном решении всегда будет что-то не так.

Вот (немного) более полный ответ на этот дублирующий вопрос: Как использовать конструкторы базового класса и присваиваниеоператор в C ++?

Кстати, если оператор присваивания является закрытым, это явный признак того, что автор базового класса очень хорошо знал, что семантика сущности и семантика значения плохо сочетается.Поверь ему, он был прав!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...