在派生 class 中使用基 class 的私有成员变量的最佳方式

Best way to use a base class's private member variable in derived class

我有以下代码,其中 base class 定义了一个纯虚函数,派生的 class 定义了这个纯虚函数以使用 base class 执行一些计算' s 私有成员变量 var (但是 var 不会被改变)。 var 通常是一些大型结构。

从设计的角度来看,我读到在这种情况下通常不赞成将 var 设为受保护的成员。实现我想要的最好方法是将 var 作为参数传递给 virtual_func()?

这激发了第二个问题。如果我想修改 virtual_func 中的 var 怎么办?这会改变你的答案吗?

class base
{
public:
  void search()
  {
    //virtual func in derived class must use var in base class, but not change var

    virtual_func();
  }

private:
  T var;
  virtual void virtual_func() = 0;
};

class derived : public base
{
  void virtual_func()
  {
    //does something with base class's var, but not alter it
  }
};

如果不想在基数class中做varprotected,可以加一个publicprotectedgetter 基类中的函数,然后您可以在派生的 class 中调用该函数。 像

T getVar() const { return var; }

"From a design perspective, I was reading that generally it is frowned upon to make var a protected member in this case."

无论您在哪里阅读,这似乎都是一个错误的概念。如果您必须在 class derived 中访问 base::var,那么 最佳设计决策是将 var 设置为 protected。其他一切都会扰乱封装。 protected 除了您的问题中提到的要求之外,还有什么用例。 :-)

Bjarne Stroustrup, in his book The Design and Evolution of C++ 在第 13.9 节中讨论了 protected

它正是为您的用例添加的:允许派生的 classes 访问基础 class 成员,而不会将这些成员暴露给所有人,或滥用 friend 声明。五年后,提出要求的人(项目)禁止使用受保护的成员变量,因为它们成为错误和复杂维护的来源。他最后说受保护的数据不是一个好主意,但受保护的成员函数很好。

按照这些准则,您应该保留所有基础 class 数据 private,并添加 protected getter 和 setter 函数来访问数据.

根据您的用例以及复制数据的成本,您的 getter 可以 return 数据的副本或对它的引用(或常量引用)。返回非常量引用将允许您通过赋值 (getVar() = newvar;) 直接修改数据,或修改 class 的特定数据成员。返回一个 const 引用,并使用一个 setter 函数,将在不过度暴露 class 的情况下更多地封装数据。 setter 函数还允许您更好地控制对 var 的更改,包括执行可能需要的任何验证。