【问题标题】: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 个问题:

  1. 为变量提供受保护的可见性有哪些风险?
  2. 是否有人对如何以干净的方式解决此错误有任何建议? (我一直在努力创建一个受保护的 getter 方法,但如果我想根据正确的上下文采取行动,我将不得不返回一个引用或指针,这与此具有相同的效果,但只需要额外的代码)。

【问题讨论】:

  • 我认为预期的解决方案是使其成为 private 并提供 protected 吸气剂。突出的风险可能是派生类型可能分配给context,而State 似乎不允许这样做。我不明白你为什么需要返回对指针的引用,关键是要防止有人让 context 指向不同的对象。 context 是指向非const 的指针,因此您仍然可以对指向的对象进行操作。编辑:上下文有一个 public 设置器,所以我猜这个推理并不真正适用。但是,这可能仍然是诊断的原因。
  • 在我看来context-&gt;transitionTo(std::unique_ptr&lt;ConcreteStateB&gt;()); 可以只是context-&gt;transitionTo(nullptr);。无论哪种情况,参数都会转换为std::unique_ptr&lt;State&gt;{nullptr}
  • 最好的办法是阅读相关的指导方针:isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-private 简而言之,受保护的比公开的要好,但仍然为子类提供了破坏您可能有的任何期望的可能性变量。
  • 你有没有想过关闭错误?

标签: c++ variables compiler-errors protected clang-tidy


【解决方案1】:
  1. 你说的不对

    我将不得不返回一个引用或指针,其效果与此相同,但只需要额外的代码

    因为通过使其受保护来暴露指针允许派生类型 操纵指针本身,而不仅仅是底层数据。

  2. 来自文档 misc-non-private-member-variables-in-classes 检查哪个 cppcoreguidelines-non-private-member-variables-in-classes 是一个 别名:

    数据成员应声明为私有并通过成员函数访问,而不是暴露给派生类或 类消费者。

【讨论】:

    猜你喜欢
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 2014-10-09
    • 2019-02-22
    • 2021-10-04
    • 2018-07-01
    • 2021-12-12
    相关资源
    最近更新 更多