运算符继承问题和 cpp 核心指南 c.128
Problem with operator inheritance and cpp core guidelines c.128
我有以下代码(我删除了一些不重要的代码):
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;
};
我已经添加了默认运算符以解决准则警告,因为我已经定义了析构函数并且我还需要定义其他内容(如果我记得的话,规则为 5)。
如果我通过启用 cpp 核心指南使用 Visual Studio 2019 构建它,我会收到以下警告:
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).
我想摆脱它,所以我按以下方式更改了代码:
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;
};
但在那种情况下,我得到以下错误:
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
我哪里做错了,如何删除指南警告?
基本上,为了覆盖任何方法,覆盖方法的签名需要与原始方法签名相同。但是,在您的情况下,签名 SimpleState& operator=(const SimpleState&)
与 State& operator=(const State&)
不同。因此,您没有覆盖原始方法,而是将方法声明为覆盖,因此出现错误。
我怀疑本例中的 C26456 警告是一个错误,另请参阅 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。
引用的核心准则条款 C.128 仅适用于虚拟成员函数,但 operator=
在您的基础 class 中不是虚拟的,并且它也没有与派生class,所以没有理由申请。
确保您确实需要 SimpleState
中的析构函数声明。你在基础 class State
中有虚函数,这似乎表明你想多态地使用 State
并且对象可能通过 State
指针而不是 SimpleState
指点。在那种情况下 State
需要声明一个虚拟析构函数,而不是 SimpleState
.
如果你在State
中声明了虚拟析构函数,那么你就不需要在SimpleState
中声明任何析构函数,它将继承State
中的虚拟析构函数。然后 SimpleState
可以遵循零规则并且不需要声明任何 copy/move 赋值运算符和 copy/move 构造函数,这是首选方式。
我有以下代码(我删除了一些不重要的代码):
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;
};
我已经添加了默认运算符以解决准则警告,因为我已经定义了析构函数并且我还需要定义其他内容(如果我记得的话,规则为 5)。
如果我通过启用 cpp 核心指南使用 Visual Studio 2019 构建它,我会收到以下警告:
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).
我想摆脱它,所以我按以下方式更改了代码:
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;
};
但在那种情况下,我得到以下错误:
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
我哪里做错了,如何删除指南警告?
基本上,为了覆盖任何方法,覆盖方法的签名需要与原始方法签名相同。但是,在您的情况下,签名 SimpleState& operator=(const SimpleState&)
与 State& operator=(const State&)
不同。因此,您没有覆盖原始方法,而是将方法声明为覆盖,因此出现错误。
我怀疑本例中的 C26456 警告是一个错误,另请参阅 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。
引用的核心准则条款 C.128 仅适用于虚拟成员函数,但 operator=
在您的基础 class 中不是虚拟的,并且它也没有与派生class,所以没有理由申请。
确保您确实需要 SimpleState
中的析构函数声明。你在基础 class State
中有虚函数,这似乎表明你想多态地使用 State
并且对象可能通过 State
指针而不是 SimpleState
指点。在那种情况下 State
需要声明一个虚拟析构函数,而不是 SimpleState
.
如果你在State
中声明了虚拟析构函数,那么你就不需要在SimpleState
中声明任何析构函数,它将继承State
中的虚拟析构函数。然后 SimpleState
可以遵循零规则并且不需要声明任何 copy/move 赋值运算符和 copy/move 构造函数,这是首选方式。