c++ - 在派生类中使用基类私有成员变量的最佳方法
问题描述
我有以下代码,其中基类定义了一个纯虚函数,派生类定义了这个纯虚函数,以使用基类的私有成员变量执行一些计算var
(var
但是不会改变)。var
通常是一些大型结构。
从设计的角度来看,我读到在这种情况下通常不赞成制作var
受保护的成员。实现我想要的最好方法是将var
作为参数传递给virtual_func()
?
这引发了第二个问题。如果我想修改var
invirtual_func
怎么办?这会改变你的答案吗?
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
}
};
解决方案
Bjarne Stroustrup在他的著作The Design and Evolution of C++中讨论protected
了第 13.9 节。
它是为您的用例而添加的:允许派生类访问基类成员,而不会将这些成员暴露给所有人,或滥用friend
声明。五年后,提出请求的人(项目)禁止使用受保护的成员变量,因为它们成为错误和复杂维护的来源。他最后说受保护的数据不是一个好主意,但受保护的成员函数很好。
遵循这些准则,您应该保留所有基类数据private
,并添加protected
getter 和 setter 函数来访问数据。
根据您的用例以及复制数据的成本,您的 getter 可以返回数据的副本或对它的引用(或 const 引用)。返回非常量引用将允许您通过赋值 ( getVar() = newvar;
) 直接修改数据,或修改类的特定数据成员。返回一个 const 引用并使用一个 setter 函数,将更多地封装数据而不会过度暴露类。setter 函数还可以让您更好地控制对 的更改var
,包括执行任何可能需要的验证。
推荐阅读
- python - Django 中的供应商权限
- java - 提供的 javaHome 不是 Eclipse 中的有效文件夹
- gremlin - Gremlin 在运行时搜索顶点并添加属性
- tensorflow - 我们可以显示与 mobilenet 的欠拟合吗?
- scala - Scala 中的 ^^^ 运算符是什么?
- iis-express - 为什么 IIS Express 锁定文件停止在 ASP.Net Core 中构建、重建和清理?
- azure-iot-hub - 在 Windows IoT Core 上将 exe 作为服务启动
- php - SELECT WHERE = sybol 不返回数据
- vue.js - 为什么某些 Vuetify 属性不能在同一个组件中工作?
- javascript - JSON 解析到对象奇怪的结果?