派生类如何使用基类的受保护成员?

Spi*_*ros 5 c++ protected private-members

假设基类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;
};
Run Code Online (Sandbox Code Playgroud)

该函数B::print只获取当前成员的值并打印它:

void B::print() const
{
  std::cout << "Value: " << value << "\n";
}
Run Code Online (Sandbox Code Playgroud)

另一个成员函数 ,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";
}
Run Code Online (Sandbox Code Playgroud)

如果other是 class 的实例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.
Run Code Online (Sandbox Code Playgroud)

这个限制对我来说听起来违反直觉。但是,我不会就此对 C++ 标准提出异议(我仍然对这一决定背后的基本原理感兴趣)。

我的问题是,在我的项目中,我确实有这种用例:派生类有一个方法,该方法采用基类的实例并需要访问接收对象的受保护成员。

最简单的解决方案,我目前实现的一个,是在基类中添加一个公共成员函数,它返回受保护的成员。这个解决方案并不完全让我满意,因为我想避免以这种方式导出成员。

如何在不通过 API 导出成员的情况下启用派生类使用基类的受保护成员?


编辑:一些相关的问题是:

我想要的答案是解决这个问题的设计模式的解释,而不会将受保护的成员暴露给外部代码(其中外部意味着不属于定义这些类的框架的一部分的代码)。

我承认,这种模式可能不存在。

cht*_*htz 5

使用成员指针实际上存在一个漏洞(没有强制转换,没有复制):

void B::compare_and_print(const A& other) const
{
  auto max_value = std::max(value, other.*(&B::value));
  std::cout << "Max value: " << max_value << "\n";
}
Run Code Online (Sandbox Code Playgroud)