2012-02-04 153 views
0

我有一些類的問題。C++類的繼承

在代碼:

class A 
{ 
public: 
    int num; 
    sayNum() { cout<<num;} 
}; 

class B : public A 
{ 
public: 
    sayNum() { cout<<"my num is: "<<num;} 
}; 

/*somewhere else...*/ 
A foo[10]; 

B something; 
something.num=10; 

foo[0]=something; 

foo[0].sayNum(); 
/*...*/ 

當我調用foo [0] .sayNum();它打印「10」,我希望它打印「我的號碼是:10」。我無法改變數組的類型。請注意,這只是一個示例代碼,如果我貼我的這將是很難理解:d)

回答

4

此線條:

foo[0]=something; 

副本東西進入數組。因爲something(即,類別B)的類型與foo[0](即類別A)的類型不同,所以存在轉換。在這種情況下,something切片,只有A部分將生存。

最終的結果是,foo[0]仍然包含class A類型的對象,因此,「我num是」將永遠輸出。

sayNum()更改爲虛擬的,這對於解決您的代碼將顯示的其他問題的好建議在此情況下無效。

如何解決它,取決於你想達到什麼。可能的解決方案是:

  • 改變數組包含指針A* foo[10];注:這意味着你將不得不使用「新」和「刪除」。
  • 使用一個std :: vector而不是一個數組:std::vector<A*> foo;額外的好處:一個向量可以隨需求增長和縮小。
  • 使用智能指針std::vector<std::shared_ptr<A> > foo;額外好處:不用擔心delete了。

但是不知道你想達到什麼目的,就不可能建議正確的方法。

1

聲明函數sayNum是在一個定義虛擬:

virtual void sayNum() { cout<<num;} 

編輯:感謝對Sjoerd的評論 - 這仍然不會幫助你。如果你想利用多態性的需要創建指向類A的一個數組而不是A級

+5

Althoug這是一個很好的建議,在這種情況下它不夠好。對陣列的分配將切片對象,並且只有A部分被複制到陣列中。 – Sjoerd 2012-02-04 14:57:49

+0

@Sjoerd所以我怎麼能存儲一個不同類的數組? – 2012-02-04 14:59:53

+0

@kittyPL通過將指針(或智能指針)存儲到要存儲的類型的公共基類中。 – Sjoerd 2012-02-04 15:10:54

1

無陣列,通過分配somethingfoo[0]將其轉換爲一個A.

這與將float分配給int類似 - 您將丟失所有小數。

1
  1. 您在各個班級中都缺少函數的返回類型。請說出您想返回類型爲void

    void sayNum() { cout<<num;}

  2. 當訪問數組元素中,使用下標上陣列對象

    例如:

    foo[0]=something;

+0

這不是他遇到的問題。 – 2012-02-04 15:04:57

+1

@izomorphius:OP的代碼甚至沒有編譯**。 – cpx 2012-02-04 15:07:36

+0

我同意。我添加了評論,表明即使你指出的問題是固定的,他的問題仍然存在。 – 2012-02-04 15:25:30

4

1.你應該避免切片
您應該使用A*而不是A。這可以幫助你理解爲什麼:What is object slicing?

2.您應聲明一個類AsayNum()功能A類的virtual
定義應該是這樣的:

class A 
{ 
public: 
    int num; 
    virtual void sayNum() { cout << num; } 
}; 

然後你的代碼,你說somewhere else可能看起來像這樣:

A* foo[10]; 

B something; 
something.num=10; 

foo[0] = &something; 

foo[0]->sayNum();