2016-04-27 60 views
1

我有一個關於虛函數或方法的問題。在stackoverflow link to post上我發現了一個非常好的帖子,解釋了虛擬函數爲什麼以及如何工作。我明白虛擬功能現在如何工作,但我仍然不明白爲什麼你需要它們。如果你看一下鏈接和所提供的例子,他創建了這樣一個實例:使用虛擬功能創建實例,爲什麼?

A *a1 = new B; 
a1->show(); 

但你爲什麼曾經想,如果你想使用的功能,從B到創建這樣一個實例?爲什麼不這樣做:

B b1 = new B; 
b1->show(); 

爲什麼我應該使用A指針,當我想要使用B引用?

我希望你們明白我對此的看法,並且可以向我解釋。

+1

你需要理解多態背後的整體思想......下面的鏈接可能有幫助... http://stackoverflow.com/questions/1031273/what-is-polymorphism-what-is-it-for-and如何使用 – Tejendra

+1

看看這個:http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list雖然任何書上的基本oop應解釋的概念。 – user2079303

+1

我在[我的回答](http://stackoverflow.com/a/27099751/464581)中給出了你鏈接到的問題的具體例子。 –

回答

2

這是一個很好的例子Polymorphism

總之,多態性允許兩種不同的類型(類)提供與不同底層實現相同的接口。

與其以A和B爲例,考慮兩個類摩托車汽車摩托車汽車可以驅動,對不對?你駕駛這兩輛車的方式是非常不同的。這兩個類應提供一個驅動器()方法,雖然他們的實現是不同的。

class Vehicle { 
    public: 
     virtual void drive() = 0; 
} 

class Car : public Vehicle { 
    public: 
     void drive() { 
      // Driving to work, however a car does that. 
     }; 
} 

class Motorcycle : public Vehicle { 
    public: 
     void drive() { 
      // Driving to work, however a motorcycle does that. 
     }; 
} 
Vehicle *car = new Car; 
Vehicle *motorcycle = new Motorcycle; 

// We can both be driven, so we share the same interface. 
car->drive(); 
motorcycle->drive(); 

這在將對象傳遞給函數時特別有用。你有一個實現正在工作的功能。你真的不在乎如何你開始工作,只要你以某種方式駕駛。

void driveToWork(Vehicle *vehicle) { 
    vehicle->drive(); 
} 

driveToWork(new Car); 

// It's Tuesday, your car broke down! 
// As long as we use a Vehicle to get to work, all is well. 
driveToWork(new Motorcycle); 
+0

這是什麼語言? – Slava

+0

C++,足以證明我的觀點至少。 – ricanontherun

+0

在C++中,通過值傳遞的對象將被切片。調用對象方法的語法不正確。如果你的意思是指針,你應該使用它們,並引入內存泄漏。 – Slava

2

擴大代碼示例以便還包括衍生自A的類C

現在添加一個功能display_A,其定義爲:

void display_A(A* aPtr) 
{ 
    a->show(); 
} 

您可以使用該功能與B一個實例,以及爲C一個實例。

B* bPtr = new B; 
C* cPtr = new C; 

display_A(bPtr); 
display_A(cPtr); 

這裏,B*C*調用display_A之前,自動轉換爲A*aPtr->show() in display_A的作品無論aPtr指向B還是C。這是創建virtual函數的真正動機。

使用

A *a1 = new B; 
a1->show(); 

的目的是爲了證明B::show()被調用,即使當指針A*類型的,如果到是什麼指針指向一個真正的B對象。

1

底線是,當你調用虛函數,則執行該功能的最派生形式,它可以。現在

class Message 
{ 
    virtual void buildMessage(); 
} 

class ShutdownMessage : public Message 
{ 
    virtual void buildMessage() { /* Do a thing. */ } 
} 

class StartupMessage : public Message 
{ 
    virtual void buildMessage() { /* Do a totally different thing. */ } 
} 

void prepareMessage(Message *M) 
{ 
    M->buildMessage(); 
} 

您可以撥打此:

prepareMessage(myMsg); 
上的任何消息

,它會調用相應的buildMessage功能。