c++ - 运算符继承问题和 cpp 核心指南 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
我做错了什么,如何删除指南警告?
解决方案
我怀疑这种情况下的 C26456 警告是一个错误,另请参阅https://developercommunityapi.westus.cloudapp.azure.com/content/problem/617702/c26456-false-positive-with-operator-in-derived-cla .html和https://developercommunity.visualstudio.com/content/problem/228085/c-core-check-false-positive-c26434.html。
引用的核心准则条款C.128仅适用于虚拟成员函数,但operator=
在您的基类中不是虚拟的,也没有与派生类中相同的签名,因此没有理由应用它。
确保你真的想要在SimpleState
. 您在基类中有虚函数State
,这似乎表明您想以State
多态方式使用并且对象可能通过State
指针而不是SimpleState
指针被销毁。在这种情况下,State
需要声明一个虚拟析构函数,而不是SimpleState
.
如果在 中声明虚拟析构函数State
,则不需要在 中声明任何析构函数SimpleState
,它将从 继承虚拟析构函数State
。然后SimpleState
可以遵循零规则,不需要任何复制/移动赋值运算符和复制/移动构造函数声明,这是首选方式。
推荐阅读
- java - 如果线程获得了对象的锁怎么办
- javascript - Blazor 子菜单
- python - 将熊猫数据框附加到数据块中的现有表中
- reactjs - React 的焦点问题
- oracle - JMeter 5.2.1 - 连接属性被忽略
- servicestack - 带有 emitLowercaseUnderscoreNames = true 的 Servicestack JsConfig 不适用于具有字母数字名称的属性
- git - 如何获取最新创建的远程 Git 分支列表?
- go - 在 Couchbase 中插入只读文档
- docker - 如何停止docker自动启动jupyter笔记本
- angular - 我使用 canDeactive 时如何使用 Skiplocation