2012-01-30 247 views
1

維基百科示例是否在this有關在C++中過濾方法的文章是否正確?C++方法覆蓋

請參考下面,我剛纔提到的註釋代碼//不正確

略困惑在C++ overiding和運行時多態性。這個演員應該做什麼?

#include <iostream> 

class Rectangle { 
public: 
    explicit Rectangle(double l, double w) : length(l), width(w) {} 
    virtual void print() const; 

private: 
    double length; 
    double width; 
}; 

void Rectangle::print() const { // print() method of base class 
    std::cout << "Length = " << this->length << "; Width = " << this->width; 
} 

class Box : public Rectangle { 
public: 
    explicit Box(double l, double w, double h) : Rectangle(l, w), height(h) {} 
    virtual void print() const; // virtual is optional here, but it is a good practice to remind it to the developer 

private: 
    double height; 
}; 

void Box::print() const { // print() method of derived class 
    Rectangle::print(); // Invoke parent print() method. 
    std::cout << "; Height= " << this->height; 
} 

int main(int argc, char** argv) { 
    Rectangle rectangle(5.0, 3.0); rectangle.print(); 
    // outputs: 
    // Length = 5.0; Width = 3.0 

    Box box(6.0, 5.0, 4.0); 
    // the pointer to the most overridden method in the vtable in on Box::print 
    //box.print(); // but this call does not illustrate overriding 

    static_cast<Rectangle&>(box).print(); // this one does 

    // outputs: 
    // Length = 5.0; Width = 3.0; Height= 4 // INCORRECT 

    //But it actually outputs Length = 6; Width = 5; Height = 4 

    getchar(); 
    return 0; 

} 
+0

是的,特定的值是錯誤的。 - 我個人認爲這個調用說明了動態調度,而覆蓋實際上意味着提供一個覆蓋。 – visitor 2012-01-30 14:25:18

+0

看起來wiki的預期輸出對我來說是錯誤的。 – 2012-01-30 14:28:10

回答

2

這一行:static_cast<Rectangle&>(box).print();具有如此代碼相同的效果將具有:

Rectangle & r = box; 
r.print(); 

和也與此代碼具有相同的效果:

Rectangle * r = &box; 
r->print(); 

It意味着創建了Box對象(Box box(6.0, 5.0, 4.0); =在運行時您會看到Box),並且存儲此對象的指針/引用的類型無關緊要。事實上,你存儲框爲Rectangle*是你在編譯時看到的。

關於重寫虛擬方法最重要的事實是關於「將調用哪個方法?」在運行時決定。

希望這會有所幫助。

3

你是對的 - 提到的輸出是不正確的。

演員只是演示一個盒子是一種矩形(從中繼承而來),即使是矩形,方法覆蓋仍然有效,方法的Box版本將被調用。

2

文章中的評論確實是錯誤的(現在已經修復);如你所說,它應該打印6,5和4。

演員陣容的目的是要證明即使您通過引用基類(Rectangle)調用虛函數,它也會調用與對象的實際類型(Box)關聯的覆蓋 - 您仍然獲得由Box::print()打印的三個值,而不是由Rectangle::print()打印的兩個值。

3

隨時修復評論在維基百科:輸出的確應該是Length = 6; Width = 5; Height = 4

另一部分是正確的,但:其中即使在Box引用了靜態轉換爲它的超類的引用的Box.print()被稱爲代碼的確是一個虛方法的重載如何在C工作++的演示。

的另一種方法來證明的相同點是通過使用指針,而不是參考的:

Rectangle *boxPtr = &box; 
boxPtr->print(); 
+0

感謝你啊@Liho。所以我可以恢復到以前的非混淆狀態。 – goldenmean 2012-01-30 14:38:04