[英]`dynamic_cast` from Base to Derived
Yes, I know that downcast using dynamic_cast
can't compile if the Base
is not polymorphic, but my problem is not about this. 是的,我知道如果
Base
不是多态的,使用dynamic_cast
downcast无法编译,但我的问题与此无关。
class Base {
public:
virtual void bar()
{
cout << "bar\n";
}
};
class Derived: public Base {
public:
void foo()
{
cout << "foo\n";
}
};
int main()
{
Base *pb;
Derived *pd;
pb = new Derived; //Base* points to a Derived object
pd = dynamic_cast<Derived*>(pb);
pd->foo(); //outputs foo
pb = new Base; //Base* points to a Base object
pd = dynamic_cast<Derived*>(pb);
pd->foo(); //outputs foo, too. Why?
}
I thought when pb = new Derived;
我
pb = new Derived;
, pb
actually points to a Derived
object lies in heap. ,
pb
实际上指向一个Derived
对象位于堆中。 After pd = dynamic_cast<Derived*>(pb);
在
pd = dynamic_cast<Derived*>(pb);
, pd
also points to that Derived
object, so pd->foo()
should be OK. ,
pd
也指向Derived
对象,所以pd->foo()
应该没问题。
But when pb = new Base;
但是当
pb = new Base;
, what pb
points to is a Base
object in heap, then after pd = dynamic_cast<Derived*>(pb);
,
pb
指向的是堆中的Base
对象,然后是pd = dynamic_cast<Derived*>(pb);
, how could pd->foo()
works? ,
pd->foo()
怎么样? Did dynamic_cast
turn the Base
object in heap into a Derived
object? dynamic_cast
是否将堆中的Base
对象转换为Derived
对象?
In C++, each instance of a class has its own version of datatypes, but all classes share the same function in memory (other than for inline functions). 在C ++中,类的每个实例都有自己的数据类型版本,但所有类在内存中共享相同的函数(除了内联函数)。 In your case, when you say something like:
在你的情况下,当你说的话:
pd->foo();
You are essentially calling Derived::foo
, which is a function in memory and the compiler knows where it is. 你本质上是调用
Derived::foo
,它是内存中的一个函数,编译器知道它在哪里。 The thing is, it is not dependent on pd
at all. 问题是,它完全不依赖于
pd
。 However, if you had something like this: 但是,如果你有这样的事情:
class Derived : public Base {
private:
int a;
public:
Derived() { a = 100; }
void foo() {
std::cout<<a<<std::endl;
}
};
Then, pd->foo()
will cause a Segmentation fault. 然后,
pd->foo()
将导致分段错误。 Here, your dynamic cast has failed and when Derived::foo
is called, it is passed 0
as the this
object. 这里,您的动态强制转换失败,当调用
Derived::foo
时,它将作为this
对象传递0
。 It was fine in the previous case, as the this
object was never used. 在前一种情况下很好,因为
this
对象从未使用过。 However, in the second case, it is used and hence, causes a Segmentation fault. 但是,在第二种情况下,它被使用,因此导致分段错误。
In your foo
you don't access this
, which in this case should be NULL
. 在你的
foo
你不能访问this
,在这种情况下应该为NULL
。 That is what dynamic_cast
returns when the cast cannot be done. 这就是当无法完成
dynamic_cast
时dynamic_cast
返回的内容。
Basically you're in the "undefined behavior" area here. 基本上你在这里的“未定义行为”区域。
You're running into undefined behavior. 您遇到了未定义的行为。 You should check the return type of
dynamic_cast
. 您应该检查
dynamic_cast
的返回类型。
pd = dynamic_cast<Derived*>(pb);
This returns null, and you call a function on a NULL
pointer. 这将返回null,并在
NULL
指针上调用函数。 Anything can happen. 任何事情都可能发生。
Please always prefer to check whether the cast is successful before trying to use it. 在尝试使用之前,请务必先检查演员表是否成功。 I guess its the advantage of using casting.
我猜它是使用铸造的优势。 You can check whether its successful or not.
你可以检查一下是否成功。
pd = dynamic_cast<Derived*>(pb);
if(pd!=NULL)
pd->foo();
If the cast fails pd
has value NULL. 如果转换失败,则
pd
值为NULL。 Do not use pd
unless you are sure it has a value. 除非您确定它具有值,否则请勿使用
pd
。 and then only de reference it 然后只引用它
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.