2013-10-20 44 views
0
#include <iostream> 

class Vehicle { 
public: 
    void greet() { 
     std::cout << "Hello, I'm a vehicle"; 
    } 
}; 

class Car : public Vehicle { 
public: 
    void greet() { 
     std::cout << "Hello, I'm a car"; 
    } 
}; 

class Bike : public Vehicle { 
public: 
    void greet() { 
     std::cout << "Hello, I'm a bike"; 
    } 
}; 

void receiveVehicle(Vehicle vehicle) { 
    vehicle.greet(); 
} 

int main() { 
    receiveVehicle(Car()); 
    return 0; 
} 

正如你可以看到覆蓋的方法,我試圖Vehicle類型的參數發送給一個函數,調用greet()關於調用一個子類當一個轉換到其超

CarBikeVehicle的子類。他們覆蓋greet()

但是,我收到「你好,我是車輛」。

我想,這是因爲接收receiveVehicle類型Vehicle,而不是一個特定的子類像CarBike的參數。但這就是我想要的:我希望這個函數能夠與Vehicle的任何子類一起工作。

爲什麼我沒有得到預期的輸出?

回答

4

有兩個問題與您的代碼:

1)當你調用receiveVehicle(Car());參數是按值接受。這意味着發生與slicing相關的問題 - 調用Vehicle的默認拷貝構造函數,從而構建您車中的Vehicle。更改爲指針或引用,使其按縮進方式工作。

例如:當鹼方法標有virtual關鍵字

void receiveVehicle(Vehicle& vehicle) { 
    vehicle.greet(); 
} 

int main() { 
    Car aCar; 
    receiveVehicle(aCar); 
    return 0; 
} 

2)多態性呼叫只發。所以,你需要做greet虛擬:

class Vehicle { 
public: 
    virtual void greet() { 
     std::cout << "Hello, I'm a vehicle"; 
    } 
}; 

對於嚴,你也可以使用const酌情:

class Vehicle { 
public: 
    virtual void greet() const { //change it also in subclasses 
     std::cout << "Hello, I'm a vehicle"; 
    } 
}; 

void receiveVehicle(const Vehicle& vehicle) { 
    vehicle.greet(); 
} 
4

只有指針和引用可以是多態的。您正在遇到切片,其中基類是從派生類構造並失去其作爲派生和所有額外數據成員的身份。

tl; dr:將您的功能更改爲接受Vehicle&(並使該參數爲非臨時),並且它將正常工作。另外,默認情況下,函數是非虛擬的,因此您需要在基類中的函數定義之前添加virtual這個詞,如virtual void greet() { ... }(感謝Diego注意)。

龍解釋

請記住,當你有一個值,編譯器必須知道多少內存來分配它。派生類可以比基類更大,所以當您從派生類構造基類時,它會丟失(切掉)派生類所攜帶的數據,並且只保留基類數據。

即使您的派生類沒有成員,因此也不會比基類大,編譯器知道一個值不能是多態的,所以它不費心從虛表中尋找虛函數該實例。它將直接調用該函數,導致靜態(非多態)行爲,並調用基類函數。

想想如果編譯器確實會調用虛擬指針會發生什麼情況:this指針會指向一個沒有派生數據的對象,因爲它被切掉了,當函數試圖訪問派生成員變量,他們不會在那裏!

+0

除了您的答案,該方法必須在基類中聲明爲虛擬。 OP的代碼丟失了。 –

+0

@DiegoGiagio的確如此,謝謝。 – Kal

1
void receiveVehicle(const Vehicle &vehicle) { 
    vehicle.greet(); 
} 
// Make your `greet` method `const` 

參照它傳遞(或指針,如果你知道有關的風險)讓多態性起作用。否則Car將被切片爲Vehicle

相關問題