假设基类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导出成员?
编辑: 一些相关的问题是:
我想要的答案是解释此问题的设计模式的解释,而不将受保护的成员暴露给外部代码(其中外部意味着,代码不属于定义这些类的框架。)
我承认,这种模式可能不存在。
答案 0 :(得分:3)
实际上存在使用成员指针的漏洞(没有强制转换,没有复制):
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";
}
答案 1 :(得分:0)
您可以使用辅助结构绕过受保护的结构:
A_Helper::GetProtectedValue(a)
您可以在other
在您的情况下,您可以将const B&
投射到static_cast
(通过reinterpret_cast
或other
),但您不知道B
的实例是否为other
类型为B
。有了这个值,读取代码的人会认为B
的类型为value_B
,并且可能会插入导致读取/写入“随机”内存的代码。
考虑班级other
有另一个成员C
而static_cast<const B&>(other).value_B
属于ID | COL1 | COL2 | COL3 | COL4 | COL5 |
---------------------------------------
1 | 8 | 35 | 42 | 12 | 27 |
2 | 22 | 42 | 35 | 8 | NULL |
3 | 18 | 22 | 8 | NULL | NULL |
4 | 42 | 12 | 27 | 35 | 8 |
5 | 18 | 27 | 12 | 22 | NULL |
类型。使用ID | Item|
1 | 8 |
1 | 35 |
1 | 42 |
. | . |
. | . |
. | . |
是未定义的行为。