具有受保护可见性的变量的风险是啥
Posted
技术标签:
【中文标题】具有受保护可见性的变量的风险是啥【英文标题】:What are the risks of variables with protected visibility具有受保护可见性的变量的风险是什么 【发布时间】:2021-09-12 18:35:29 【问题描述】:我正在尝试实现example 中解释的状态模式。我已经编写了类似如下的代码。
class State
public:
virtual void enter() ;
virtual void update() = 0;
virtual void exit() ;
virtual void setContext(Context* cxt)
this->context = cxt;
protected:
Context* context;
;
class Context
public:
void do_something();
void do_something_else();
void transitionTo(std::unique_ptr<State> next_state)
if (state != nullptr)
state->exit();
state = std::move(next_state);
state->setContext(this);
state->enter();
private:
std::unique_ptr<State> state;
;
class ConcreteStateA : public State
public:
void update() override
try
context->do_something();
catch
context->transitionTo(std::unique_ptr<ConcreteStateB>());
;
class ConcreteStateB
// ...
;
但是,当我尝试使用 clang-tidy 编译它时,我收到以下警告
error: member variable 'context' has protected visibility [cppcoreguidelines-non-private-member-variables-in-classes,-warnings-as-errors]
我有以下 2 个问题:
-
为变量提供受保护的可见性有哪些风险?
是否有人对如何以干净的方式解决此错误有任何建议? (我一直在努力创建一个受保护的 getter 方法,但如果我想根据正确的上下文采取行动,我将不得不返回一个引用或指针,这与此具有相同的效果,但只需要额外的代码)。
【问题讨论】:
我认为预期的解决方案是使其成为private
并提供 protected
吸气剂。突出的风险可能是派生类型可能分配给context
,而State
似乎不允许这样做。我不明白你为什么需要返回对指针的引用,关键是要防止有人让 context
指向不同的对象。 context
是指向非const
的指针,因此您仍然可以对指向的对象进行操作。编辑:上下文有一个 public
设置器,所以我猜这个推理并不真正适用。但是,这可能仍然是诊断的原因。
在我看来context->transitionTo(std::unique_ptr<ConcreteStateB>());
可以只是context->transitionTo(nullptr);
。无论哪种情况,参数都会转换为std::unique_ptr<State>nullptr
。
最好的办法是阅读相关的指导方针:isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-private 简而言之,受保护的比公开的要好,但仍然为子类提供了破坏您可能有的任何期望的可能性变量。
你有没有想过关闭错误?
【参考方案1】:
你说的不对
我将不得不返回一个引用或指针,其效果与此相同,但只需要额外的代码
因为通过使其受保护来暴露指针允许派生类型 操纵指针本身,而不仅仅是底层数据。
来自文档
misc-non-private-member-variables-in-classes 检查哪个
cppcoreguidelines-non-private-member-variables-in-classes
是一个
别名:
数据成员应声明为私有并通过成员函数访问,而不是暴露给派生类或 类消费者。
【讨论】:
以上是关于具有受保护可见性的变量的风险是啥的主要内容,如果未能解决你的问题,请参考以下文章