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 导出成员的情况下启用派生类使用基类的受保护成员?
编辑:一些相关的问题是:
我想要的答案是解决这个问题的设计模式的解释,而不会将受保护的成员暴露给外部代码(其中外部意味着不属于定义这些类的框架的一部分的代码)。
我承认,这种模式可能不存在。
使用成员指针实际上存在一个漏洞(没有强制转换,没有复制):
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)