2011-10-04 83 views
8

我認爲動態類型是指使用new動態分配的對象。在下面的情況下,你說p指向動態類型還是靜態類型的對象?在標準中,它並沒有說動態類型是動態對象。什麼是動態類型的對象

1.3.3 - 左值表達式將左值表示爲 的最大派生對象(1.8)的類型引用。 [示例:如果指針(8.3.1)p的靜態類型是「指向類B」的指針指向類D D的對象,從B(條款10)派生,則動態類型的表達式* p 是「D」。參考文獻(8.3.2)的處理方式相似。 ]

而且這是什麼下面的報價意味着

動態類型右值表達的是它的靜態類型

class Base { 
    virtual void foo(){} 
}; 

class Derived : public Base { 
    void foo(){} 
}; 

int main() 
{ 
    Derived d; 
    Base *p = &d; 
} 

回答

19

我認爲動態類型是指動態分配的對象 使用新的。

沒有。

動態類型是可以通過指向其實際類型的基本類型的引用(包含指針)來訪問的對象的實際類型。

也就是說,如果我們有:

class A { 

}; 

class B : public A { }; 


B l; 
A& k = l; 

這裏k爲類型A的一個對象的引用,但真正的類型稱爲對象,它的動態型,是B.

這裏的「動態」具有「只在運行時才知道」的含義。

+0

+1清晰,簡潔,很好的例子。 – Lou

+3

+1,但我想你可以通過添加一個根本不使用新的例子來更清楚地說明這個例子。 –

+0

'A&k = B();'是否就夠了? – arne

5

靜態類型是類型該變量是編譯時間中已知的唯一類型(因此被認爲是靜態的 - 不能更改)。 動態類型是實際被指向的對象的類型運行時間。這裏的動態意味着它只在運行時才知道,這意味着它可能會改變(即一個變量可以指向各種類型的各種對象)。

在此內容中使用new與您自己的示例所示不相關。在你的主體中,d的靜態和動態類型是Derived,因爲它不是指針或引用。但是,p的靜態類型爲Base,但在您的代碼中,動態類型爲Derived

3

在靜態類型語言中,例如C++或Java,static可能引用編譯時已知的信息,而dynamic引用運行時已知的信息。

例如:

struct Base { virtual std::string name() const { return "Base"; } }; 

struct Derived: Base { std::string name() const { return "Derived"; } }; 

void print(Base const& b) { std::cout << b.name() << "\n"; } 

print方法中,static類型的bBase const&。因此,編譯器將檢查所調用的所有方法是否存在於Base對象的上下文中。

然而,當執行到來時,調用name,因爲該方法是虛擬的,則相對於dynamic類型的對象進行的:

  • 這可能是Base
  • 這可能是Derived
  • 這可能是另一個派生類Base我們知道沒有

因此,在下面的例子:

int main(int argc, char* argv[]) { 
    if (argc == 1) { 
    Base base; 
    print(); 
    } else { 
    Derived derived; 
    print(derived); 
    } 
}; 
  • staticdynamic和類型的baseBasederivedDerived
  • print方法中,static類型的bBase(總是)
  • 根據參數的數目,的bdynamic要麼BaseDerived

它是一個當前錯誤的假設該多態性必須基於動態內存分配,但是這兩個概念雖然不是正交的,但在某些情況下可以互不使用。

-1

動態內存分配總是在運行時完成,可以使用「new」關鍵字來實現。 但在你的問題* p = & d中提到了另外一種情況,因爲你已經使基類函數爲「虛擬」,它告訴編譯器通過它處理「p」而不是它所屬的指針的類型.so這是動態內存分配之一,因爲編譯器永遠不會知道在運行時要存儲哪個類對象的地址,它只知道它是哪種類型的指針(即Base類指針或派生類指針)。