简体   繁体   English

为什么没有static_cast会失败?

[英]Why does this fail without static_cast?

Compiling f works, but compiling g fails with an error. 编译f有效,但编译g失败并出现错误。

Why does this happen? 为什么会这样?

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;
}

A static_cast forces a conversion that is potentially unsafe. static_cast强制转换可能不安全。

B* b = static_cast<B*>(a);

This would be valid if a pointed to an A object that actually was the base class sub-object of a B object, however it doesn't. 这将是有效的,如果a指向的A ,实际上是一个基类子对象的对象B对象,然而事实并非如此。 The cast forces the conversion. 演员强制转换。

B* b = a;

There is no cast here and there is (correctly) no implicit conversion allowed from base class pointer to derived class pointer. 这里没有强制转换,并且(正确地)没有允许从基类指针到派生类指针的隐式转换。 A pointer to a derived class can always be converted to a pointer to a base class because a derived class object always contains a base class sub-object but not every base class instance is a sub-object of a particular derived class type. 指向派生类的指针始终可以转换为指向基类的指针,因为派生类对象始终包含基类子对象,但并非每个基类实例都是特定派生类类型的子对象。

Well, yeah. 嗯,是的 Doing: 这样做:

B* b = new A();

Is unsafe. 不安全。 You end up with a B pointer to an A object; 最终得到一个指向A对象的B指针; you never construct the B portion of the object; 你永远不会构造对象的B部分; your object is "sliced". 你的对象是“切成薄片”。

On the other hand... 另一方面...

A* a = new B();

...would be fine. ......会没事的。

You are trying to convert a pointer from A* to B*. 您正在尝试将指针从A *转换为B *。 I am not sure what you are trying to achieve. 我不确定你想要实现的目标。 But since B* is derived from A* and not the other way around this is not valid. 但由于B *来自A *而不是相反,这是无效的。 Maybe you want to do something like this: 也许你想做这样的事情:

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();

}

Yes, it does give an error if you want to assign a base class to a derived class pointer type. 是的,如果要将基类分配给派生类指针类型,它确实会出错。 No, it doesn't give an error if you explicitly cast the pointer type, because in C++ you are allowed to shoot yourself in the foot if you so desire. 不,如果您明确地转换指针类型,它不会给出错误,因为在C ++中,如果您愿意,您可以自己射击。

What exactly is baffling you, or what did you expect to achieve with your code? 究竟是什么令你感到困惑,或者你期望用你的代码实现什么目标?

A base class cannot be implicitly converted to a derived class. 基类不能隐式转换为派生类。 Just consider this 考虑一下

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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM