启用对非 public 继承的转换的技巧

A trick to enable casting over non-public inheritances

这是与我的 相关的跟进,我在其中调查了问题并发现向上和向下转型似乎在 public 继承关系上正常工作。例如,这段代码甚至无法编译:

class A {
};

class B : protected A {
};

int main() {
  B b;
  static_cast<A*>(&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);
      |                     ^

不过,我想我找到了以下技巧来克服这个限制。 我们可以在 class 内部进行转换,然后将转换功能导出为 public 方法:

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

我承认不是很漂亮。我的测试(在更复杂的代码中)显示它有效,但我仍然不确定。

它是有效的 C++ 代码和正确的做法吗?

概念上 getA 没问题。 B 正在选择公开其中的 A。可以简化为return this;,不需要强制转换。

我对fromA有所保留,因为它暗示所有A都是B,这可能不是真的。您应该将 fromA 的可访问性限制在可以证明所有 A 都是 B 的地方。

Safe downcast may be done with dynamic_cast.

static_cast

上的 cppreference