遭遇C++基礎問題 [2004年5月29日 18:33 ]

用VC++有一段時間了,卻發現用VC這麼久,C++其實沒學到什麼。基本的不能再基本了,真正用起來還有深有體會的感覺。

需要定義三個對象,一個基類A,另外兩個A1,A2從這個基類派生。說起來也就是用不用Virtual的問題,很簡單,或許是沒有注意過,或許注意過,也像這次一樣靈犀一動,也在不經意的時候就忘記了,要不是現在開始在Linux下面寫程序,還不知道什麼時候能在注意起來。寫一寫,或許下次我就能很快地想起了。其實,試一下也就出來了,不是嗎?

class A
{
 CList m_lsPoint;
 virtual void AddPoint()
        {
  m_lsPoint.Add(CPoint(0,0));
 }
 CList m_lsPoint2;
 void AddPoint2()
        {
  m_lsPoint2.Add(CPoint(0,0));
 }
};
class A1:public A
{
 void AddPoint()
 {
  m_lsPoint.Add(CPoint(1,1));
 }
 void AddPoint2()
 {
  m_lsPoint2.Add(CPoint(1,1));
 }
};
上面基類A中兩個AddPoint的區別是一個有virtual,一個沒有。測試代碼如下:

 A1 *a1=new A1;
  ((A*)a1)->AddPoint();
 ((A*)a1)->AddPoint2();

上面兩個函數的調用方法一樣,可是最後查看m_lsPoint和m_lsPoint2的列表卻發現加進去的點是不一樣的m_lsPoint的點是(1,1),而m_lsPoint2的點是(0,0)。對此,作如下感想:

1.virtual修飾的是虛函數,顧名思義是從他派生出來以後,基類的這個函數就不再創建出來。A的AddPoint函數。AddPoint2沒有用virtual修飾,雖然在直接調用a1->AddPoint2()的時候,並不執行a->AddPoint2(),但是,可以通過指針轉換,來得到實際上存在的A類的AddPoint2函數。

2.A1從A派生,即A1具有了A的所有屬性,比如一個學生的班級,學號屬性在A中,A1中包含了他的各門功課成績。要更新該學生的班級或者學號,但是實際上獲得的信息只有A類的成員(班級,學號),如果直接從A1更新(即連同各成績),必然會產生錯誤。這時候,需要的是不使用virtual關鍵字的基類。結構如下:

                                    |-班級
          | ——學生——|
          |                         |-學號
學生  |
信息  |——語文成績
          |——數學成績
          |——。。。
3.在用VC的時候經常也會用到virtual關鍵字,不過常常是直接在繼承的時候用這種方法。比如

 void A1::AddPoint()
 {
  A::AddPoint();
  m_lsPoint.Add(CPoint(0,0));
 }

這種方法就變成了上面說到的那樣,一次把基類,派生類的屬性(成員)都更新了。但是,如果基類不是Virtual這樣做就沒有用了。想到,要是在A1::AddPoint2中也像這樣加上父類的函數又沒效呢?發現沒效,再用這樣((A*)this)->AddPoint2();也同樣無用。這下我就不懂了。世上我不懂的事情太多了。

VC中的OnDraw,OnPaint之類的函數,也是virtual,卻不調用基類的函數。按照1的思考,基類的這些函數就不用創建出來,也就節省了內存。是嗎?不是嗎?

暈!一直都在用MFC,根本不用去考慮類的結構,佈局,一切按照微軟佈下的模板走路。真是失敗,也該學學自己走路了。基類的結構真得很重要,就做類似上面那樣的幾個類,當然派生出來的不只有A1一個,卻因爲基類定義得太差,想改,卻是別人寫的,而且他是老員工,失敗。派生類我在用,爲了多幾個接口,連本該基類寫的東西,也放到派生類寫了(屢次要求無效)。所謂面對對象的程序,實在鬱悶。

這次在Unix下面做程序,纔有以上遭遇,學學Linux,Unix,VI,有新事物出現,我又有動力了。

我。。。還。。。活着!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章