在派生 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中做var
protected
,可以加一个public
或protected
getter 基类中的函数,然后您可以在派生的 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
的更改,包括执行可能需要的任何验证。
我有以下代码,其中 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中做var
protected
,可以加一个public
或protected
getter 基类中的函数,然后您可以在派生的 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
的更改,包括执行可能需要的任何验证。