C++ 启用对非公共继承进行强制转换的技巧
这是一篇与我的研究相关的后续文章,我调查了这个问题,发现在公共继承关系上,向上和向下的预测似乎是正确的。例如,此代码甚至不编译:C++ 启用对非公共继承进行强制转换的技巧,c++,language-lawyer,protected,static-cast,upcasting,C++,Language Lawyer,Protected,Static Cast,Upcasting,这是一篇与我的研究相关的后续文章,我调查了这个问题,发现在公共继承关系上,向上和向下的预测似乎是正确的。例如,此代码甚至不编译: class A { }; class B : protected A { }; int main() { B b; static_cast<A*>(&b); }; A类{ }; B类:受保护的A类{ }; int main(){ B B; 静态浇铸(&b); }; G++给出了以下错误: t.cc: In function ‘int
class A {
};
class B : protected A {
};
int main() {
B b;
static_cast<A*>(&b);
};
A类{
};
B类:受保护的A类{
};
int main(){
B B;
静态浇铸(&b);
};
G++给出了以下错误:
t.cc: In function ‘int main()’:
t.cc:10:21: error: ‘A’ is an inaccessible base of ‘B’
10 | static_cast<A*>(&b);
| ^
t.cc:在函数“int main()”中:
t、 抄送:10:21:错误:“A”是“B”的不可访问的基
10 |静态铸造(&b);
| ^
然而,我认为我发现了以下技巧来克服这个限制。我们可以在类内部强制转换,然后将强制转换功能导出为公共方法:
#包括
甲级{
};
B类:受保护的A类{
公众:
A*getA(){
返回静态_cast(此);
};
静态B*来自A(A*A){
返回静态_-cast(a);
};
};
int main(){
B B;
//甚至不编译
//std::cout从概念上讲getA
很好。B
选择公开其中的A
。可以简化为返回此;
,不需要强制转换
我对fromA
有所保留,因为这意味着所有A
s都是B
s,这可能不是真的。您应该将fromA
的可访问性限制在可以证明所有A
s都是B
s的地方
可以使用dynamic\u cast
进行安全向下广播
在我看来,上的cppreference很好。A
是基类的事实被声明为受保护的
实现细节,并且通过使getA
成为成员函数,该实现细节不会“泄漏”然而,如果我需要这个,我会重新思考我的设计;实现继承不是经常的最佳工具。<代码>保护< /COD>基类是我在C++中的20年编程中没有找到的一个很好的应用。@ RSAHU<代码> BASE<代码>是一组W它有一个定义良好、范围狭窄且稳定的操作集。派生的
是一组狗,在它上面有一个更为狭窄的允许操作集,并添加了一些额外的功能。你想写尽可能干净且优化的代码。你是如何做到的?我看不到任何好处。在我看来,B
要么是a
,要么是not.如果不是,getA
没有意义,如果是,它应该公开继承。好吧,对于不同结构的代码,我的观点可能会不同:)。我非常不喜欢dynamic\u cast
。C/C++的本质是在编译时对运行时的性能进行所有测试。
#include <iostream>
class A {
};
class B : protected A {
public:
A* getA() {
return static_cast<A*>(this);
};
static B* fromA(A* a) {
return static_cast<B*>(a);
};
};
int main() {
B b;
// Does not even compile
//std::cout << static_cast<A*>(&b);
// works like charm
std::cout << b.getA() << '\n';
// works also in the reverse direction, although it needs a static method
std::cout << B::fromA(b.getA()) << '\n';
};