static_cast和指针引用

5

有人能告诉我为什么这段代码无法编译吗:

struct A { };
struct B : public A { };

int main()
{
  B b;
  A* a = &b;
  B* &b1 = static_cast<B*&>(a);
  return 0;
}

现在,如果您将静态转换替换为:
B* b1 = static_cast<B*>(a);

然后它就编译了。

编辑:很明显,编译器将A*B*视为独立类型,否则这段代码会起作用。问题更多地是关于为什么要这样做?


2
a 不是指针的引用,而是指针。 - andre
@MrLister B*& 是指向 B 的指针的引用。 - Some programmer dude
FYI,使用dynamic_cast会更安全。 - dchhetri
只有在程序逻辑上无法确定强制类型转换是否有效时,使用 dynamic_cast 才能强制编译器将运行时类型信息嵌入到该类层次结构中。由于 dynamic_cast 操作相对较慢,因此除非必要,否则不建议使用这种解决方案。 - Agentlien
3
dynamic_cast 在这里是不合法的。 - James Kanze
4个回答

7

B 是从 A 派生的,但 B* 并不是从 A* 派生的。 指向 B 的指针并不是指向 A 的指针,它只能被转换为一个指向 A 的指针。但是这些类型仍然是不同的(转换可能会改变指针的值)。B*& 只能引用 B*,而不能引用其他任何指针类型。


3

非常量左值引用(B*&)无法绑定到不相关的类型(A*)。


0

引用的处理是编译器为您完成的,不需要强制转换为引用。

如果我们重构代码为:

B b;
A* a = &b;
B* b_ptr = static_cast<B*>(a);
B*& p1 = b_ptr;

它将会编译通过。


1
我同意(请参见我的帖子),但这并没有做到相同的事情。例如,更改“p1”中的指针并不会更改“a”中的指针。 - PierreBdR

-1

你正在尝试将 A* 强制转换为 B*。这是错误的方式,也不是很有用。你可能想要将指向派生类的指针存储在指向基类的指针中,这是有用的,甚至不需要强制转换。

我想这里可能可以使用 dynamic_cast,但如果我没记错的话,结果是实现定义的。


1
你不能使用 dynamic_castA* 转换为 B*&。这是不合法的,代码将无法编译。 - James Kanze
A* 转换到 B* 是唯一一个使用 static_cast 有意义的方向。在另一个方向上,没有什么可以做的。 - PierreBdR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接