启用对非 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
.
上的 cppreference
这是与我的
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
的地方。
上的 cppreferenceSafe downcast may be done with
dynamic_cast
.