当 A 和 B 没有共同祖先时,通过 dynamic_cast 从 A* 转换为 B* 是否有效?
Is it valid to cast from A* to B* via dynamic_cast when A and B haven't a common ancestor?
clang 3.5.0和g++4.9.0fine编译以下代码(使用-std=c++11 -Wall -Wextra -pedantic-errors
),程序输出true
:
#include <iostream>
struct A
{
virtual ~A() = default;
};
struct B
{
virtual ~B() = default;
};
struct C : A, B
{
virtual ~C() = default;
};
int main()
{
C c;
A* ap = &c;
B* bp = dynamic_cast<B*>(ap);
std::cout << std::boolalpha << (bp != nullptr) << std::endl;
}
是。这有时被称为交叉投射,如果它们都是同一派生对象的基子对象,就会成功,就像这里一样。
dynamic_cast
是必要的,因为转换需要运行时信息,这两者都是C
对象的一部分。要进行静态转换,必须先显式转换为C*
。
是的,根据§5.2.7[expr.dynamic.cast],对于dynamic_cast<T>(v)
(强调矿):
如果C是T指向或引用的类类型,则运行时检查逻辑执行如下:
--如果在v指向(引用)的最派生对象中,v指向(参考)公共基类C对象的子对象,并且如果只有一个类型为C的对象是从v指向(引用)的子对象派生的,则结果指向(参考)该C对象。
--否则,如果v指向(引用)最派生对象的公共基类子对象,并且派生次数最多的对象的类型有一个C类型的基类,它是明确的和公共的,结果指向(引用)派生次数最多对象的C子对象
--否则,运行时检查将失败。
在您的案例中,v
引用了一个派生程度最高的对象,该对象是C
的实例,但v
的静态类型是指向公共基类A
的指针。报价单中提到的C
基类就是您的B
。
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 如何理解C++标准N3337中的expr.const.cast子句8
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 覆盖 CAST 运算符(我认为它被称为向下转换)
- C++错误,隐 <function-style-cast> 式要求使用模板化类一次调用多个构造函数的多个转换
- 如何修复<function-style-cast>错误:无法从'initializer list'转换为asdending比较<W>(模板函子)
- 错误 C2440: 'type cast':无法从 'bool' 转换为 'CString'
- <function-style-cast> 错误:无法从'initializer list'转换为'std::thread'