Why C++ requires public inheritance, ignoring friend declarations, to make dynamic downcast working?

佐手、 提交于 2020-08-19 11:15:52

问题


Here we have a class B, inherited from class A, and it has a friend class C. Being a friend, C should have access to everything in B, including the A base class.

To test it,

  1. first we create a B instance.
  2. we upcast its address to an A*
  3. then we try downcast it with dynamic_cast<> again to B*.

The expected result is to get back the address of the original B instance.

#include <cstdint>
#include <cstdio>

class A {
  public:
    virtual ~A() {};
};

class C;

class B : protected A { // <- this should be public to work! Why?
  friend C;
};

class C {
  public:
    void doit() {
      B *b = new B();
      printf("b= %p\n", b);
      A *a = static_cast<A*>(b);
      printf("a= %p\n", a);
      B *bb = dynamic_cast<B*>(a);
      printf("bb=%p\n", bb);
      delete b;
    };
};

int main() {
  C c;
  c.doit();
  return 0;
};

The common problem in similar cases, that the base class has to be polymorph (which is guaranted here by its empty virtual destructor), is here solved.

However, the dynamic casting still does not work: bb should have the same adress as b.

My experiments show, the only way to make it working, if A is a public base class of B. But... C is a friend of B. It does not work even as protected.

Why is it so?

I use gcc-8, if it matters.


回答1:


Summarizing the useful infos and cited resources in the comments, a self-answer can be written.

First, the friend declaration is a no-issue: friend affects only the accessibility of the members of the class where it is declared on, but not its base class(es).

Second, accessibility check in C++ goes in compilation time. But the accessibility check of dynamic_cast happens in runtime. This accessibility check is far more restrictive, and the dynamic_cast can happen only if the inheritance is public.

Its likely reason is that doing it correctly would probably require different rtti tables for the different access levels.



来源:https://stackoverflow.com/questions/62430684/why-c-requires-public-inheritance-ignoring-friend-declarations-to-make-dynam

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!