2011-09-18 41 views
0

我有兩個班,其中一個繼承其他:從對象使用導出函數列表對象內部

class baseClass 
{ 
public: 
    virtual void show(); 
}; 

void baseClass::show(){cout << "Base class" << endl;} 


class derivedClass 
{ 
public: 
    void show(); 
}; 

void derivedClass::show(){cout << "Derived class" << endl;} 

如果我做一個derivedClass對象,並呼籲展示功能,它正確地打印「派生類」。如果我這樣做:

derivedClass b; 
baseClass* b; 
b=&d; 
b->show(); 

它再次正確地打印出「派生類」。 但是,如果我做一個列表,像這樣:

list<baseClass> t; 
list<baseClass>::iterator it; 
baseClass b; 
derivedClass d; 
t.push_back(b); 
t.push_back(d); 

並嘗試撥打顯示在每個項目上:

it = t.begin(); 
it->show(); 
it++; 
it->show(); 

兩個b和d輸出爲「基地班」。 我的問題是:爲什麼它只使用showCode()的baseClass版本,以及如何才能正確使用派生版本中的derivedClass對象在列表中?

在此先感謝

回答

1

您必須聲明的方法show()virtual使多態性工作:

class baseClass 
{ 
public: 
    virtual void show(); 
}; 

void baseClass::show(){cout << "Base class" << endl;} 


class derivedClass : public baseClass 
{ 
public: 
    virtual void show(); 
}; 

void derivedClass::show(){cout << "Derived class" << endl;} 

你也失蹤class derivedClass : public baseClass

最後的問題。你需要使用指針。

list<baseClass*> t; 
list<baseClass*>::iterator it; 
baseClass b; 
derivedClass d; 
t.push_back(&b); 
t.push_back(&d); 

,並改成這樣:

it = t.begin(); 
(*it)->show(); 
it++; 
(*it)->show(); 
+0

我的壞,那是在這個問題(這是我editted)錯誤,顯示()是在基類虛。正如你所說,我已經嘗試在derivedClass中使show()虛擬,但它仍然沒有調用正確的函數。 – James

+0

我得到了相同的結果。它與迭代器有關。給我一秒來更新我的答案。 – Mysticial

+0

感謝捆綁包,(* it)是我一直困住的部分(昨天也試過*和*(它))。<)現在完美地工作 – James

0

它再次正確地打印出 「派生類」。但是,如果我列出這樣的列表:

不。它不能打印「派生類」。事實上,這條線:

b=&d; 

會給compilation error,因爲b不是d多態基地。

申報showvirtual,在基類:

virtual void show(); 

然後,將編譯。

然而,即使使show虛擬,推派生類的對象,向列表中後會引起對象切片因爲列表只能包含基類對象;這意味着,該列表將獲得派生類對象的子對象。這是因爲您已將該列表聲明爲:

list<baseClass> t; 

這是不正確的。

聲明爲:

list<baseClass*> t; 

,推動pointer反對這一點,就像這樣:

derivedClass d; 
derivedClass *pd = new derivedClass; 
baseClass b; 

t.push_back(&d); 
t.push_back(pd); //note there is no `&` 
t.push_back(&b); 

//use t 

//must delete pd 
delete pd; 

-

只是做出說明,如果你想刪除的派生類的對象,使用類型基類的指針,如下所示:

baseClass *bptr = new derivedClass(); 
delete bptr; 

那麼你必須將baseClass的析構函數定義爲虛擬的,否則上面的delete語句將調用未定義的行爲。

所以做到這一點:

class baseClass: 
{ 
    //... 
    virtual ~baseClass(); 
}; 
+0

您能澄清你的意思嗎?「insert pointer to object to這個」? 另外,如果我嘗試列表噸; \t list :: iterator it; t.push_back(&b); \t t.push_back(&d); 然後它 - >顯示();想出了一個錯誤(表達式必須有指針類型) – James

+0

@Alexdander:。編輯後現在參見 – Nawaz

+0

由於一個一起幫忙,用你的回覆和Mysticial一起,它的功能就像一個魅力=) – James