簡體   English   中英

`dynamic_cast`從Base到Derived

[英]`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_castdynamic_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM