2013-10-07 53 views
0

我正在學習C++。我在運行時多態下有問題嗎? 爲什麼我們需要使用引用/指針時,通過創建類的對象可以完成相同的工作?引用和指針用於多態嗎?

`爲例如:

class A{ 
private: 
    int p; 
public: 
    A(){} //ctor 
    void Print(){} 
    void display(){} 
    void showrecord(){} 
} 
class B:public A 
{ 
Private: 
    int q; 
public: 
    B(){} //ctor 
    void Print(){} 
    void displayrecord(){} 
} 

現在在上述情況下,我可以通過使用它的對象和類方法b。使用範圍的分辨率,然後爲什麼要使用指針和分配對象將其訪問乙類的任何方法?

+2

您的示例沒有使用多態性。 – juanchopanza

+0

你的意思是有'Print'和'print'嗎? DId你的意思是使任何功能虛擬? – doctorlove

+0

看看這個答案:http://stackoverflow.com/a/9260064/1168156;) – LihO

回答

1

可以說你有3輛不同的汽車。而你有不同的駕駛機制。司機不需要知道底層的引擎,但只有如何駕駛汽車的協議,即按此踏板加速,按踏板剎車等。

現在從駕駛員的角度來看,沒關係如果它的本田,福特或別克。從他的觀點來看,這只是一輛汽車。同樣,如果你已經下了車,停在哪裏,你可以稱他們爲車棚。它安置了汽車,並且不會爲每一件汽車造成什麼困擾。所以

std::vector<Car*> v; 
v.push_back(new Ferrari()); 
v.push_back(new Honda()); 
v.push_back(new Ford()); 

爲什麼我們需要使用引用/指針時,同樣的工作可以通過創建類的對象呢?

如果沒有指針或引用,則無法創建具有某種共同性但在某些特定意義上不同的對象集合。這通過使所有對象派生自基類(稱爲Object),在一些嚴格的OOP語言(如Java,C#等)中繞過。 C++是一種多範式語言,程序員可以自由地做出適合他/她項目的決策。一種在C++中完成的方法是通過基類的指針。這個習語被稱爲運行時多態。

for (const auto &this_car : v) 
    this_car->drive(); 

這裏不考慮實際作,矢量v就能抱上車,只要在基類car是類型的一部分。同樣,每個品牌的drive都會有所不同,但這並不需要爲調用它的功能所知。

編輯:

感謝nijansen用於指出這個帖子並沒有真正回答這樣的問題:爲什麼要爲運行時多態性的指針或引用(動態類型)?它只是說他們必須用它來實現它,但並不能解釋爲什麼我們不能使用普通(靜態類型)變量。

C++的設計方式使得對象的類型在編譯時可能完全知道,也可能不知道類型。在Circle c;中,我們知道cCircle類型;而在Shape *p = make_shape();我們真的不知道什麼對象p指向; p自己的類型是Shape*,但其指向對象的具體類型未知。我們所知道的是它指向一些源於Shape的對象。請不要將自己與動態或自動內存分配混淆;這對於自動變量也是如此。 Shape *p = &c;。在這裏,p也是孤立的,編譯器不知道該對象是什麼具體類型,其中p指向哪個類型。

如果我們寫p爲靜態(非指針,非引用)型Shape p = make_shape();Shape p = c;真正發生的事情slicingp將具體類型Shape的,自它不是一個指針,它會複製(形狀)部分Circle對象c它,這是最不希望的。

不知道底層類型,我們如何調用正確的具體類型的函數? C++提供了虛擬功能來完成這項工作。這就是爲什麼運行時多態性總是用C++中的虛擬方法解釋的原因;而在諸如Java和C#all methods are virtualall object types are references/pointers的語言中。在某種程度上,對您的問題的回答是,該語言的設計使得需要運行時多態性參考/指針變量

+0

這就是解釋多態性,但不是這個問題:「爲什麼我們需要在創建類的對象時完成同樣的工作時使用引用/指針?」我已經標記的可能的重複覆蓋這個很好 – nijansen

+0

@nijansen:我現在添加它。謝謝! – legends2k

0

給你一個普通的例子,

請原諒pseduocode。將添加一段cpp的代碼在一段時間後,現在有點生疏

超級類

Class Animal 
{ 

} 

子類

Class Dog : public Animal 
{ 

} 

Class Cat : public Animal 
{ 

} 

另一類,

class Vet 
{ 
    void checkAnimal(recieve Animal) 
    { 

    }   
} 

現在考慮這種用法,

vetObject.checkAnimal(dogObject); 
vetObject.checkAnimal(catObject); 

如果不是因爲多態性獸醫類本來這樣的事情,

class Vet 
{ 
    void checkAnimal(recieve Cat) 
    { 

    }   

    void checkAnimal(recieve Dog) 
    { 

    }   

    .... and so on 
} 
0

從而可以做一些通用processess到每個對象。例如,您有Chicken : Animal班,並且您有Cow : Animal班,並且它們具有常用功能doSlaughter(),並且您有SlaughterHouseJob班。當您想要處理slaughterHouseJob.doSlaughterAnimals()方法時,您可以簡單地編寫此代碼:

for(Animal animal:animals){ 
    animal.doSlaughter(); //It can be chicken or Cow or other animals. Simply one function for all jobs 
}