3

I've following code (I've removed some code not important here):

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

I've added default operators due to solve a guideline warning since I've defined the destructor and I need to define also other stuff (rule of 5 if I remember).

If I build it with Visual Studio 2019 by enabling cpp core guidelines, I obtain the following warnings:

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).

I want to get rid of it, so I've changed the code in following way:

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

But in that case I obtain the following errors:

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

What I'm doing wrong and how can I remove the guideline warning?

5
  • 2
    I suggest you go for the rule of zero instead. Let the compiler generate the constructors, destructors and assignment operators for you instead. Commented Feb 13, 2020 at 10:47
  • 1
    I did it at first and I've obtained another cpp core guidelines warning telling me that a virtual destructor is explicit for a derived class. I've added it and then I've obtained this issue. Commented Feb 13, 2020 at 10:57
  • 1
    @Jepessen The core guidelines are guidelines, not more. You must evaluate in each case whether a change is necessary or not and you need to read the corresponding section in github.com/isocpp/CppCoreGuidelines/blob/master/… to determine how and whether to act. Just adding stuff because the warning says so will only make it worse. Commented Feb 13, 2020 at 10:59
  • Then please read the first sentence of the rule of three (which applies to the rule of five as well): "If a class requires a user-defined destructor ..." (emphasis mine). If you don't explicitly define (implement) your destructor, you're not breaking the "rule". Commented Feb 13, 2020 at 10:59
  • Ok thanks for suggestion. We're starting now to testing the guidelines so we need to elaborate more experience with them. Commented Feb 13, 2020 at 11:01

2 Answers 2

3

I suspect that the C26456 warning in this case is a bug, see also https://developercommunityapi.westus.cloudapp.azure.com/content/problem/617702/c26456-false-positive-with-operator-in-derived-cla.html and https://developercommunity.visualstudio.com/content/problem/228085/c-core-check-false-positive-c26434.html.

The referenced core guideline clause C.128 applies only to virtual member functions, but operator= is not virtual in your base class and neither does it have the same signature as in the derived class, so there is no reason for it to apply.


Make sure that you really want the destructor declaration in SimpleState. You have virtual functions in the base class State, which seems to indicate that you want to use State polymorphically and that objects might be destroyed through State pointers, rather than SimpleState pointers. In that case State needs to have a virtual destructor declared, not SimpleState.

If you declare the virtual destructor in State, then you won't need to declare any destructor in SimpleState, which will inherit the virtual destructor from State. Then SimpleState can follow the rule-of-zero and wont need any of the copy/move assignment operators and copy/move constructors declared, which is the preferred way.

Sign up to request clarification or add additional context in comments.

2 Comments

That was my original intent. I've added the virtual destructor because cpp core guidelines were complaining about the fact that it was missing, so I've added it and then they were complaining about the rule of 5. So basically I can return to my original code that had implemented rule of zero in SimpleState.
@Jepessen Yes, but don't forget to add virtual ~State() = default; to State. You may then default the copy/move operations in State to satisfy the rule-of-5 for it.
0

Basically, in order to override any method, the signature of the overriding method needs to be identical with the original method signature. In your case however, the signature is different SimpleState& operator=(const SimpleState&) vs State& operator=(const State&). You are therefore not overriding the original method, but declaring the method as override, hence the error.

1 Comment

State& operator=(const State&) is not virtual in the first place, so it can never be overridden, which is why I suspect the warning to be a bug.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.