2013-10-09 39 views
0

我在獲取對象向量以打印派生類名稱而不是基類時出現問題。使用具有派生類值的基類函數

這些都是我的班

#include <vector> 
#include <iostream> 

using namespace std; 

class Object 
{ 
    string name; 
public: 
    string getName() 
    { 
     return name; 
    } 
}; 

class Flashlight : public Object 
{ 
    string name = "Flashlight"; 
public: 
    string getName(); 
}; 

這是我的主,它具有對象的載體,在這一點上只需要打印出他們的名字。

int main() 
{ 
    vector<Object> items; 
    items.push_back(*new Flashlight); 

    for(int i = 0; i < items.size(); i++) 
    { 
     cout << i+1 << " " << items.at(i).getName(); 
    } 
} 

現在如果我在對象分配的東西的名稱,將打印,但它不是使用派生類的價值觀,我只是希望它繼承了函數,那麼它用自己的價值觀。我試過在基類中實現函數(但是看到我將來可能會有很多這樣的代碼會導致大量冗餘代碼),但這也不起作用。

+0

你需要有指針向量 – ST3

+1

你的代碼遭受對象切片。因爲你有一個'矢量',所以當你將它添加到你的矢量中時,任何'手電筒'都被*切成一個對象。你需要一個'矢量'。您的代碼還有其他問題,但我想他們只是試圖糾正對象分割的基本錯誤。 – john

+0

@john:重寫成員變量的嘗試是同樣嚴重的問題。兩者都必須解決。 –

回答

1

試試這個方法:

int main() 
{ 
    vector<Object *> items; 
    items.push_back(new Flashlight); 

    for(int i = 0; i < items.size(); i++) 
    { 
     cout << i+1 << " " << items.at(i)->getName(); 
    } 
} 

而且在另一個答覆中提到這將是很好用virtual方法讀到它here.

更重要的是,你需要使用構造函數來設置變量值name。你可以閱讀他們here

你應該試試這種方法:

class Object 
{ 
private: 
    string name; 
public: 
    Object() : name("Object") 
    {} 
    Object(string str) : name(str) 
    {} 

    string getName() 
    { 
     return name; 
    } 
}; 

class Flashlight : public Object 
{ 
public: 
    Flashlight() : Object("Flashlight") 
    {} 

    string getName(); 
}; 
+0

這只是問題的一部分。該變量仍未正確初始化。 –

+0

是的,這工作,我早些時候嘗試使用指針,但使用它們錯了,謝謝你的幫助! – breezy

+0

@ user2861504如果確實有幫助,您應該接受一個答案。這就是SO系統的工作原理 – 2013-10-09 07:13:05

3

而是在派生類中聲明變量「名稱」的,初始化的變量值作爲派生類的自定義值。另外,我會建議你讓getName方法爲虛擬。如果您只想輸出名稱,您也不需要在派生類中重寫getName方法。

+0

這只是問題的一部分。該集合是Object,而不是手電筒。 –

+0

如果您不在派生類中重新定義名稱變量,並使用構造函數/設置器或其他東西來初始化派生類中的名稱(在基本中定義)的值,該怎麼辦? –

+0

這就是你應該做的,是的。 –

1

您的代碼有兩個問題:

  1. getName()不虛。這意味着調用的實際函數是在編譯時根據變量靜態的類型決定的。因此,如果您的變量類型爲Object,Object&Object*(或其中的任何const變體),函數Object::getName()將被調用,無論您的變量引用或指向的對象的實際類型如何(動態類型)。
  2. 您有一個vector<Object>,這意味着存儲在其中的所有對象都是Object類型。您可以嘗試放置一個​​對象,但只有Object部分將被複制到該向量中。如果在vector<>中需要多態性,則需要一個指針向量(或更好的智能指針)。

所以,你必須做兩件事情,以獲得所需的行爲:

  1. 聲明函數getName()virtual string getName()(甚至 更好,virtual const string& getName() const
  2. 聲明itemsvector<Object*> items(甚至更好,使用 適當的智能指針,例如​​而不是原始的 指針)
相關問題