问题描述
假设基类 A
定义了受保护的成员。派生类 B
使用此成员。
Say that a base class A
defines a protected member. A derived class B
uses this member.
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
当前成员的值并打印出来:
The function B::print
just takes the value of the current member and prints it:
void B::print() const
{
std::cout << "Value: " << value << "\n";
}
另一个成员函数 B :: compare_and_print
,使用 A
的实例,检查其值并打印两者的最大值:
The other member function, B::compare_and_print
, takes an instance of A
, checks their values and prints the maximum of both:
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
实例一起使用。不幸的是,这并不能编译。 c是这样说的:
If other
were an instance of the class B
, this would be no problem. But the function would like to work with any kind of A
instances. This does unfortunately not compile. This is what clang says about this:
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.
此限制对我来说似乎违反直觉。但是,我不会对此提出异议(尽管我对此决定背后的原理很感兴趣)。
This restriction sounds counter-intuitive to me. However, I'm not going to dispute the C++ standard about this (I'm nevertheless interested about the rationale behind this decision).
我的问题是在我的项目中我确实有这种用例:派生类的方法带有基类的实例,并且需要访问接收对象的受保护成员。
My problem is that in my project I really have this kind of use case: A derived class has a method that takes an instance of the base class and needs to access a protected member of the received object.
我当前实现的最简单的解决方案是在基类中添加一个公共成员函数,该函数返回受保护的成员。此解决方案不能完全满足我的需要,因为我想避免以这种方式导出成员。
The easiest solution, the one I implemented currently, is to add a public member function to the base class, which returns the protected member. This solution does not fully satisfy me because I would like to avoid exporting the member this way.
如何启用对基类受保护成员的使用
编辑:
是否与派生类通过API导出成员无关?问题是:
Some related questions are:
- Accessing protected members in a derived class
- How to access protected members in a derived class?
我想得到的答案是对一种设计模式的解释,以解决此问题而不将受保护的成员暴露给外部代码(其中 external 表示,该代码不属于框架的一部分)
The answer I would like to have is the explanation of a design pattern to solve this problem without exposing the the protected member to the external code (where external means, code that is not part of the framework defining these classes).
它我承认,可能是这样的模式不存在。
It could be that such a pattern cannot exist, I acknowledge.
推荐答案
实际上存在使用成员指针的漏洞(没有强制转换,没有复制):
There is actually a loophole using member pointers (no casting, no copying):
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";
}
这篇关于派生类如何使用基类的受保护成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!