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';
};