首页 > 试题广场 >

有如下代码: struct A1{ virtual

[单选题]
有如下代码:
struct A1 {
    virtual ~A1() {}
};
struct A2 {
    virtual ~A2() {}
};
struct B1 : A1, A2 {};

int main() {
    B1 d;
    A1* pb1 = &d;
    A2* pb2 = dynamic_cast<A2*>(pb1);  //L1
    A2* pb22 = static_cast<A2*>(pb1);  //L2
    return 0;
}
  • L1语句编译失败,L2语句编译通过
  • L1语句编译通过,L2语句编译失败
  • L1,L2都编译失败
  • L1,L2都编译通过
vs2015上面L2无法编译...
编辑于 2020-09-27 19:10:12 回复(0)
    因为dynamic_cast是在运行时进行类型检查的,指针pb1指向了基类对象d,在运行时dynamic_cast能知道pb1真正指向的对象d,所以用dynamic_cast<A2*>(pb1)其实就是把A1*指向B1转换成了A2*指向B1
    而static_cast是在编译时进行转换的,A1*和A2*是两个不同的指针类型,不能进行转换。
    如果把
A2* pb2 = dynamic_cast<A2*>(pb1);
A2* pb22 = static_cast<A2*>(pb1);
    换成
A2* pb2 = dynamic_cast<A2*>(&d);
A2* pb22 = static_cast<A2*>(&d);
    就没有错误了
    这道题考的应该是static_cast的编译时期转换和dynamic_cast的运行时期转换
发表于 2020-12-28 08:51:03 回复(2)

在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

向上转换,即为子类指针指向父类指针(一般不会出问题);向下转换,即将父类指针转化子类指针。

向下转换的成功与否还与将要转换的类型有关,即要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。

发表于 2020-09-20 12:23:46 回复(0)
 A2* pb2 = dynamic_cast<A2*>(pb1);  //L1
        因为dynamic_cast是根据虚表的内容确定是否存在继承关系来判断是否可转换,所以pb1转换成A1*类型也不影响dynamic_cast的判断,对比虚表中的内容所以不会被转型欺骗,而static_cast本来不存在继承关系的 类型随便转型成存在继承关系的类型就可以欺骗static_cast,让它认为可以进行转换。而且因为运行时才有对象,也才有虚表,所以dynamic_cast只有在运行时才能判断是否可以转换

 A2* pb22 = static_cast<A2*>(pb1);  //L2
        因为static_cast只是单纯凭两类型判断是否满足继承关系来判断是否可转换(父转子或子转父均可),所以pb1转换成A2*就会影响static_cast ,而且因为类型在编译时 就  确定了,所以static_cast编译期就可以判断是否可以转换。
编辑于 2021-11-01 06:47:24 回复(0)

代码中的 L2 语句编译失败的原因是因为static_cast进行静态类型转换时,只能在拥有继承关系的类之间进行转换。而在这里,A1和A2是独立的基类,并没有直接的继承关系。

虽然在结构体B1中同时继承了A1和A2,但是由于它们是独立的基类,相互之间没有继承关系,因此无法使用static_cast直接将指向A1的指针转换为指向A2的指针。

相比之下,L1 语句中使用的是dynamic_cast,它用于在运行时进行类型转换,并且可以处理多态类型(至少有一个虚函数)之间的转换。因此,在 L1 语句中,虽然pb1指针的静态类型是A1*,但是它指向的是一个同时继承了A1和A2的对象,所以可以通过dynamic_cast将其转换为A2*类型的指针。

总结起来,static_cast只能进行相关类之间的静态类型转换,而dynamic_cast则可以在运行时进行多态类型之间的转换。在这个例子中,因为A1和A2是独立的基类,没有直接的继承关系,所以无法使用static_cast进行转换,但可以使用dynamic_cast进行转换

发表于 2023-08-26 17:25:44 回复(0)

Static_cast from 'A1 *' to 'A2 *', which are not related by inheritance, is not allowed
clion报错,二者没有继承关系,不能做类型转换

发表于 2022-03-10 11:31:52 回复(0)
上行转换:把子类的指针或引用转换为基类表示 下行转换:把基类指针或引用转化成指针或引用 上行转换,dynamic_cast和static_cast是一样的;下行转化,dynamic_cast具有static_cast所没有的动态类型检查功能。
发表于 2022-01-17 20:21:09 回复(0)
为啥使用gcc编译,是L2有问题?
发表于 2020-12-20 11:02:12 回复(1)