假设一个基类 A
定义了一个受保护的成员。一个派生类 B
使用这个成员。
class A
{
public:
A(int v) : value(v) { }
protected:
int value;
};
class B : public A
{
public:
B(int v) : A(v) { }
void print() const;
void compare_and_print(const A& other) const;
};
函数
B::print
仅获取当前成员的值并将其打印:void B::print() const
{
std::cout << "Value: " << value << "\n";
}
另一个成员函数
B::compare_and_print
,接受一个A
实例,检查它们的值并打印两者中的最大值:void B::compare_and_print(const A& other) const
{
auto max_value = std::max(value, other.value);
std::cout << "Max value: " << max_value << "\n";
}
如果
other
是类B
的实例,那么这就没问题了。但是函数希望能够处理任何类型的A
实例。不幸的是,这段代码无法编译。下面是clang对此的报告:test.cpp:27:42: error: 'value' is a protected member of 'A'
auto max_value = std::max(value, other.value);
^
test.cpp:9:7: note: can only access this member on an object of type 'B'
int value;
^
1 error generated.
这个限制对我来说听起来有些违反直觉。不过,我不会对C++标准提出异议(我仍然对这个决定背后的理由感兴趣)。
我的问题是,在我的项目中,我真的有这样一种用例:派生类有一个方法,它接受基类的实例,并需要访问所接收对象的受保护成员。
最简单的解决方案,也是我目前实现的方案,是向基类添加一个公共成员函数,该函数返回受保护的成员。这种解决方案并不能完全满足我,因为我想避免以这种方式导出成员。
如何使派生类能够使用基类的受保护成员而不通过API导出成员?
编辑:
我想要的答案是一种设计模式的解释,可以解决这个问题,而不必将受保护的成员暴露给外部代码(其中外部意味着不是定义这些类的框架的一部分的代码)。
可能不存在这样的模式,我承认。
A::value
吗?如何从派生类函数中调用父类函数?。因此,需要创建一个getter函数。 - Brighter sidefriend
关键字? - songyuanyaofriend
,每当一个新的派生类需要访问受保护的成员时,我需要编辑基类,这违反了开放封闭原则。这不是我正在寻找的干净解决方案。(顺便说一句,我可能希望在基类中隐藏某些数据,通过将其设为私有) - Spiros