Tengo el siguiente código (he eliminado algún código que no es importante aquí):

class State {
public:

  virtual void enter() = 0;
  virtual void update() = 0;
  virtual void exit() = 0;
};

class SimpleState : public State {
public:

  SimpleState() = default;
  SimpleState(const SimpleState&) = default;
  SimpleState(SimpleState&&) = default;
  virtual ~SimpleState() = default;

public:

  void enter() override;
  void update() override;
  void exit() override;

public:

  SimpleState& operator=(const SimpleState&) = default;
  SimpleState& operator=(SimpleState&&) = default;
};

Agregué operadores predeterminados para resolver una advertencia de guía ya que definí el destructor y necesito definir también otras cosas (regla de 5 si no recuerdo mal).

Si lo compilo con Visual Studio 2019 al habilitar las pautas principales de cpp, obtengo las siguientes advertencias:

SimpleState.hpp: warning C26456: Operator 'SimpleState::operator=' hides a non-virtual operator 'State::operator=' (c.128).
SimpleState.hpp: warning C26456: Operator 'SimpleState::operator=' hides a non-virtual operator 'State::operator=' (c.128).

Quiero deshacerme de él, así que he cambiado el código de la siguiente manera:

class State {
public:

  virtual void enter() = 0;
  virtual void update() = 0;
  virtual void exit() = 0;

public:

  virtual State& operator=(const State&) = 0;
  virtual State& operator=(State&&) = 0;
};

class SimpleState : public State {
public:

  SimpleState() = default;
  SimpleState(const SimpleState&) = default;
  SimpleState(SimpleState&&) = default;
  virtual ~SimpleState() = default;

public:

  void enter() override;
  void update() override;
  void exit() override;

public:

  SimpleState& operator=(const SimpleState&) override = default;
  SimpleState& operator=(SimpleState&&) override = default;
};

Pero en ese caso obtengo los siguientes errores:

SimpleState.hpp: error C3668: 'SimpleState::operator =': method with override specifier 'override' did not override any base class methods
SimpleState.hpp: error C3668: 'SimpleState::operator =': method with override specifier 'override' did not override any base class methods

¿Qué estoy haciendo mal y cómo puedo eliminar la advertencia de la guía?

1
Jepessen 13 feb. 2020 a las 13:44

2 respuestas

La mejor respuesta

Sospecho que la advertencia C26456 en este caso es un error, consulte también https://developercommunityapi.westus.cloudapp.azure.com/content/problem/617702/c26456-false-positive-with-operator-in-derived-cla .html y https : //developercommunity.visualstudio.com/content/problem/228085/c-core-check-false-positive-c26434.html.

La cláusula de referencia principal referenciada C.128 solo se aplica a funciones miembro virtuales, pero operator= no es virtual en su clase base y tampoco tiene la misma firma que en la clase derivada, por lo que no hay razón para que se aplique.


Asegúrese de que realmente desea la declaración del destructor en SimpleState. Tiene funciones virtuales en la clase base State, lo que parece indicar que desea utilizar State polimórficamente y que los objetos podrían destruirse a través de punteros State, en lugar de SimpleState punteros En ese caso, State necesita tener un destructor virtual declarado, no SimpleState.

Si declara el destructor virtual en State, no necesitará declarar ningún destructor en SimpleState, que heredará el destructor virtual de State. Entonces SimpleState puede seguir la regla de cero y no necesitará ninguno de los operadores de asignación de copia / movimiento y constructores de copia / movimiento declarados, que es la forma preferida.

2
walnut 13 feb. 2020 a las 11:20

Básicamente, para anular cualquier método, la firma del método de anulación debe ser idéntica a la firma del método original. Sin embargo, en su caso, la firma es diferente SimpleState& operator=(const SimpleState&) vs State& operator=(const State&). Por lo tanto, no está anulando el método original, sino declarando el método como anulación, de ahí el error.

0
sfun 13 feb. 2020 a las 10:57