编译 f 有效,但编译 g 失败并显示错误。
为什么会这样?
class A {
public:
A() {}
};
class B : public A {
public:
B() {}
};
void f() {
A* a = new A();
B* b = static_cast<B*>(a);
}
void g() {
A* a = new A();
B* b = a;
}
答案 0 :(得分:4)
static_cast
强制进行可能不安全的转化。
B* b = static_cast<B*>(a);
如果a
指向实际上是A
对象的基类子对象的B
对象,则此方法有效,但事实并非如此。演员强迫转换。
B* b = a;
这里没有强制转换,并且(正确地)没有允许从基类指针到派生类指针的隐式转换。指向派生类的指针始终可以转换为指向基类的指针,因为派生类对象始终包含基类子对象,但并非每个基类实例都是特定派生类类型的子对象。
答案 1 :(得分:3)
B* b = new A();
不安全。最终得到一个指向A对象的B指针;你永远不会构造对象的B部分;你的对象是“切成薄片”。
另一方面......
A* a = new B();
......会没事的。
答案 2 :(得分:1)
您正在尝试将指针从A *转换为B *。我不确定你想要实现的目标。但由于B *来自A *而不是相反,这是无效的。也许你想做这样的事情:
int main()
{
///The above code compiles while if I replace above two line in main with below assignment it gives error.
A *a=new A();
A * b=new B();
}
答案 3 :(得分:1)
是的,如果要将基类分配给派生类指针类型,它确实会出错。不,如果你明确地使用指针类型,它不会给出错误,因为在C ++中,如果你愿意的话,你可以用脚射击自己。
究竟令你感到困惑的是什么,或者你希望用你的代码实现什么目标?
答案 4 :(得分:0)
无法将基类隐式转换为派生类。试试这个
class A {
public: int x;
};
class B : public A {
public: int y;
};
B* b = new A; // assume it works, so 4 bytes is allocated and initialized.
b->y; // bam! accessing unallocated region.