使用受保护的继承公开基类转换函数
Posted
技术标签:
【中文标题】使用受保护的继承公开基类转换函数【英文标题】:Making Base Class Conversion Functions Public with a Protected Inheritance 【发布时间】:2021-07-22 02:02:03 【问题描述】:我有一个继承自另一个的类。我不希望此类的用户意外地在子对象上使用基类函数。显而易见的答案是使继承受保护或私有。
但是,我确实希望将子对象隐式转换为基类。此强制转换的默认实现在大多数情况下是隐藏的,因为它被赋予受保护/私有状态,并且尝试定义用户转换会引发警告:
"converting ‘B’ to a reference to a base class ‘A’ will never use a type conversion operator [-Wclass-conversion]"
很公平。由于这条路对我关闭,我必须转过来问:有没有办法将默认类型转换重新分类到公共空间,以便隐式转换可以继续存在?
作为我正在努力工作的一个例子:
class A
public:
A()
A(A& otherA)
;
class B : protected A
public:
operator A& ()
return *this;
;
int main()
B guy;
A otherguy(guy);
遗憾的是,我不能只将基类中的违规函数声明为受保护:如果用户显式转换为该基类,我希望它们可用。在我的特殊情况下,B 不包含任何数据,只是 A 周围的便利/安全包装,因此我无需担心通过允许此转换来切片或以其他方式丢失任何信息。我只是不希望用户将后端 API(目前通过公共继承公开)误认为是对用户更友好的包装 API 的一部分。
【问题讨论】:
如果目标是让用户确认他们正在转换,您是否考虑过只使用一个显式函数,例如B.convert_to_a
?必须写 guy.convert_to_a()
清楚地表明我理解转换的后果。
我有一个这样的函数,它提供了我希望他们进入后端 API 的显式转换。但是,我不想重写当前隐式转换性质的 B 的每次使用来调用该显式函数。许多请求 A 的函数目前在我的代码库中接受 B。我也不想规范化调用显式转换,因为在每种情况下都需要它。
【参考方案1】:
我不认为你可以按照你要求的方式做你想做的事。
我会使用封装而不是继承:
class A
public:
T func1(); // should be visible via B
void func2(); // should not be visible via B
;
class B // note: not inheriting from A
A base; // B explicitly defines its "base class sub-object"
public:
// provide access to base class sub-object
operator A&() return base;
// provide access to func1
T func1() return base.func1();
;
void use(A &a) a.func2();
int main()
B b;
b.func1(); // no problem
// b.func2(); // won't work;
use(b); // no problem. Uses our conversion operator
【讨论】:
以上是关于使用受保护的继承公开基类转换函数的主要内容,如果未能解决你的问题,请参考以下文章