2010-01-04 47 views
0

我試圖添加對象到「內容」向量,並使用show()在他們所有。 但是,「基地」的兒童(A,B)的對象表現得像他們的「基地」類型, 什麼不是我的意圖。看起來,我試圖使用虛擬功能,但它不起作用。對象的向量

我希望代碼能夠說明問題。

class Base { 
    public: 
     virtual void show() { cout << "Base "; } 
}; 

class A : public Base { 
    public: 
     virtual void show() { cout << "A "; } 
}; 

class B : public Base { 
    public: 
     virtual void show() { cout << "B"; } 
}; 



vector<Base> content; 

void add(Base &o) { 
    content.push_back(o); 
} 

A test1; 
B test2; 

add(test1); 
add(test2); 

for (size_t i = 0; i < content.size(); i++) { 
     collection[i].show(); // output is: Base Base instead of A B 
} 

在此先感謝。

回答

0
vector<Base*> content; // << 

void add(Base *o) { // << 
    content.push_back(o); 
} 

A test1; 
B test2; 

add(&test1); // << 
add(&test2); // << 

for (size_t i = 0; i < content.size(); i++) { 
     collection[i]->show(); // << 
} 
+1

作爲答案的代碼通常無法描繪很多信息。你需要解釋它:它解決了什麼問題,它是如何解決的,等等。另外,你不提「delete」。編輯:接受;哦,諷刺。 – GManNickG 2010-01-04 21:59:30

+2

GMan:沒有'new',沒有'delete' – swegi 2010-01-04 22:03:19

+0

夠公平的,但這並不是它將如何用於真正的代碼。它將使用'new'和'delete'。 – GManNickG 2010-01-04 22:05:02

1

STL容器存儲值對象。你在這裏所稱的切片

3

你有什麼是基地的向量。
當您將某些東西添加到矢量中時,它將被複制到矢量中但是隻有基礎件正在被複制。因此,你將失去所有的惡意信息。

這被合理地稱爲切片問題。

一個簡單的解決方案是將指針存儲在向量中。

+0

更好的解決方案是在向量中存儲智能指針。 :-) – 2010-01-04 23:51:32

0

你必須使用vector<Base*>,因爲目前您在添加傳遞對象將被複制Base的新對象。

2

正如其他人所說,你正在經歷切片。 vector存儲Base,並且任何派生的信息被切掉。

與指針緩解這個:

std::vector<Base*> v; 
v.push_back(new A); 
v.push_back(new B); 

現在的問題是釋放你的資源。在向量超出範圍之前,您需要遍歷它並刪除每個元素。更嚴重的問題是例外。

如果在矢量的生命週期中的任何時候,如果拋出異常,它將展開堆棧,在某個時刻釋放向量中的所有指針;一個巨大的內存泄漏。

如果您使用更專用的容器,則可以避免此問題。要麼自己寫一個(當然不推薦),要麼使用boost pointer containers