[英]`dynamic_cast` from Base to Derived
是的,我知道如果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?
}
我pb = new Derived;
, pb
實際上指向一個Derived
對象位於堆中。 在pd = dynamic_cast<Derived*>(pb);
, pd
也指向Derived
對象,所以pd->foo()
應該沒問題。
但是當pb = new Base;
, pb
指向的是堆中的Base
對象,然后是pd = dynamic_cast<Derived*>(pb);
, pd->foo()
怎么樣? dynamic_cast
是否將堆中的Base
對象轉換為Derived
對象?
在C ++中,類的每個實例都有自己的數據類型版本,但所有類在內存中共享相同的函數(除了內聯函數)。 在你的情況下,當你說的話:
pd->foo();
你本質上是調用Derived::foo
,它是內存中的一個函數,編譯器知道它在哪里。 問題是,它完全不依賴於pd
。 但是,如果你有這樣的事情:
class Derived : public Base {
private:
int a;
public:
Derived() { a = 100; }
void foo() {
std::cout<<a<<std::endl;
}
};
然后, pd->foo()
將導致分段錯誤。 這里,您的動態強制轉換失敗,當調用Derived::foo
時,它將作為this
對象傳遞0
。 在前一種情況下很好,因為this
對象從未使用過。 但是,在第二種情況下,它被使用,因此導致分段錯誤。
在你的foo
你不能訪問this
,在這種情況下應該為NULL
。 這就是當無法完成dynamic_cast
時dynamic_cast
返回的內容。
基本上你在這里的“未定義行為”區域。
您遇到了未定義的行為。 您應該檢查dynamic_cast
的返回類型。
pd = dynamic_cast<Derived*>(pb);
這將返回null,並在NULL
指針上調用函數。 任何事情都可能發生。
在嘗試使用之前,請務必先檢查演員表是否成功。 我猜它是使用鑄造的優勢。 你可以檢查一下是否成功。
pd = dynamic_cast<Derived*>(pb);
if(pd!=NULL)
pd->foo();
如果轉換失敗,則pd
值為NULL。 除非您確定它具有值,否則請勿使用pd
。 然后只引用它
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.