2017-11-11 244 views
1

下面是一個示例程序是什麼我談論:C++ - 呼兒方法將覆蓋在家長的名單

#include <iostream> 
#include <list> 

using namespace std; 

class Thing { 
    public: 
     virtual void jump() { cout << "Called from Thing class" << endl; } 
}; 

class Car: public Thing { 
    public: 
     virtual void jump() { cout << "Vroom vroom; imma car biotch" << endl; } 
}; 

int main(int argc, char* argv[]) { 

    Car myCar; 

    list<Thing> myList; 

    myList.push_back(myCar); 

    std::list<Thing>::iterator iterator; 
    for (iterator = myList.begin(); iterator != myList.end(); ++iterator) { 
     iterator->jump(); 
    } 

    return 0; 
} 

輸出:

Called from Thing class 

我想要什麼要做的是列出「事情」。我希望能夠從Thing類中添加子類的實例;那麼我希望能夠從迭代器中調用它們的覆蓋函數。

唯一的問題是,即使在使用「虛擬」關鍵字時,迭代器也會使用Thing :: jump函數,而不是Car :: jump函數。

我該怎麼做才能使它不僅適用於Car,而且還包括Thing,Car等所有覆蓋「跳轉」功能的潛在子類。

+5

多態性需要一個指針或引用的位置。你正在做的是切分你的派生對象,以便它變成簡單的基礎類型對象。 –

+0

術語檢查:它是「覆蓋」和「重寫」。 – molbdnilo

回答

0

在C++值是他們說他們是。你有一個Thing列表不是一個列表Thing或派生類型。

當您在列表中插入某些東西時,會創建它的一個副本。在插入派生類型實例的情況下,這會複製對象的部分,即所謂的對象切片(將部分切掉)。

存在多種方式來存儲多態數據,但基本類型的實例不是其中之一。例如,您可以將std::unique_ptr<Base>存儲在您的列表中,例如:

例如,您可以將std::unique_ptr<Base>存儲在您的列表中。如果這樣做,請確保您的基本類型具有虛擬析構函數,以避免在默認的刪除器中刪除未定義的行爲。

#include <iostream> 
#include <list> 
#include <memory> 

class Thing { 
public: 
    virtual void jump() { std::cout << "Called from Thing class\n"; } 
    ~Thing(){} 
}; 

class Car: public Thing { 
public: 
    virtual void jump() { std::cout << "Vroom vroom; I am a car\n"; } 
}; 

然後在主:

std::list<std::unique_ptr<Thing>> myList; 

myList.push_back(std::make_unique<Car>()); 

for(auto&& ptr:myList){ 
    ptr->jump(); 
} 
+0

我得到:** main.cpp:18:15:錯誤:'unique_ptr'不是'std'的成員** – Griffort

+1

@Griffot您是否將您的編譯器設置爲支持C++ 11?如果沒有,請看看[這裏](https://stackoverflow.com/questions/10363646/compiling-c11-with-g) – HJuls2

+0

@griff也是'#include '它的定義。 – Yakk