程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 深度探索C++對象模型(3)

深度探索C++對象模型(3)

編輯:C++入門知識
  介紹
  
  多態是一種威力強大的設計機制,答應你繼續一個抽象的public接口之後,封裝相關的類型,需要付出的代價就是額外的間接性--不論是在內存的獲得,或是在類的決斷上,C++通過class的pointer和references來支持多態,這種程序風格就稱為"面向對象".   大家好,雷神關於《深度探索C++對象模型》筆記終於又和大家見面了,速度慢的真是可以。好了不浪費時間了,直接進入主題。
  這篇筆記主要解決了幾個經常被人問到的問題。
  1、C++支持多重繼續嗎?
  2、結構和類的區別是什麼?
  3、如何設計一個面向對象的模型?   C++支持多重繼續(Java和C#不支持多重繼續),雖然我想我可能一輩子用不到它這一特性(C++是雷神的業余愛好),但至少我要知道它可以。典型的多重繼續是下面這個:
   //iostream 從istream 和 ostream 兩個類繼續。
  class iostream:public istream,public ostream
  {......};   結構strUCt和類class到底有沒有區別?VCHELP上前幾天還看到一個帖子在討論這個問題。其實結構和類真的沒什麼區別,不過我們需要把握的是什麼時候用結構好,什麼時候用類好,當然這沒有嚴格的規定。通常我們混合使用它們,從書上的例子,我們可以看出為什麼還需要保留結構,並且書上給出了一個方法:
   struct C_point{.......}; //這是一個結構
  class Point
  {
  public:
  operator C_point(){return _c_point;}
  //....
  private:
  C_point _c_point;
  //....
  }   這種方法被成為組合(composition).它將一個對象模型的全部或部分用結構封裝起來,這樣做的好處是你既可以在C++中應用這個對象模型,也可以在C中應用它。因為struct封裝了class的數據,使C++和C都能有合適的空間布局。   面向對象模型是有一些彼此相關的類型,通過一個抽象的base class(用來提供接口),被封裝起來。真正的子類都是通過它派生的。當然一個設計優秀的對象模型還必須考慮很多的細節問題,雷神根據自己的理解寫出一個面向對象模型的代碼,大家可以看看,高手請給指出有沒有問題。雷神先謝了。
  
  思路:我想要實現一個人員治理治理的對象模型,雷神一直在思考一個人員治理的組件(當然最終它會用C#實現的一個業務邏輯對象,並通過數據庫控制對象和數據庫進行交互,通過WEB FORM來顯示界面)。這裡借用一下自己的已經有的的想法,用C++先進行一下實驗,由於只是為了體會面向對象的概念,我們采用面向對象的方法實現一個鏈表程序,而且沒有收集信息的接口。信息從mina()函數顯式給出。
  
  這個對象模型應該可以實現對人員的一般性治理,要求具備以下功能:
  
  創建一個人員信息鏈表
  添加、刪除人員信息
  顯示人員信息 //*************************************************
  //PersonnelManage.cpp
  //創建人:雷神
  //日期:2002-8-30
  //版本:
  //描述:
  //************************************************* #include
  #include
  //基類,是此對象模型的最上層父類
  class Personnel
  {
  friend class point_list; //用來實現輸出鏈表,以及插入或刪除人員的功能.
  protected:
  char serial_number[15];//編號
  char name[10];//名稱
  char passWord[15]//口令
  Personnel *pointer;
  Personnel *next_link;
  public:
  Personnel(char *sn,char *nm,char *pwd)
  {
  strcpy(serial_number,sn);
  strcpy(name,sm);
  strcpy(password,pwd);
  next_link=0;
  }
  Personnel()
  {
  serial_number[0]=NULL;
  name[0]=NULL;
  password[0]=NULL;
  next_link=0;
  }
  void fill_serial_number(char *p_n)
  {
  strcpy(serial_number,p_n);
  }
  void fill_name(char *p_nm)
  {
  strcpy(name,p_nm);
  }
  void fill_password(char *p_pwd)
  {
  strcpy(password,p_pwd);
  }
  
  virtual void addnew(){}
  virtual void display()
  {
  cout<<" 編號:"<   cout<<"名字:"<   cout<<"口令:"< }
  };
  //下面是派生的子類,為了簡單些我在把子類進行了成員簡化。
  //思路:由父類派生出成員子類,正式成員要求更具體的個人資料,這裡省略了大部份.
  //並且正式成員可以有一些系統的操作權限,這裡省略了大部份。
  //正式成員子類
  
   class Member:public Personnel
  {
  friend class point_list;
  private:
  char member_email[50];
  char member_gender[10];
  double member_age;
  public:
  Member(char *sn,char *nm,char *pwd,char *em,char *gd,double ag):Personnel(sn,nm,pwd)
  {
  strcpy(member_email,em);
  strcpy(member_gender,gd);
  member_age=age;
  }
  Member():Personnel()
  {
  member_email[0]=NULL;
  member_gender=NULL;
  member_age=0.0;
  }
  void fill_email(char *p_em)
  {
  strcpy(member_email,p_em);
  }
  void fill_gender(char *p_gd)
  {
  strcpy(member_gender,p_gd);
  }
  void fill_age(double ages)
  {
  member_age=ages;
  } void addnew()
  {
  pointer=this;
  }
  void display()
  {
  Personnel::display()
  cout<<"電子郵件:"<   cout<<"性別:"<   cout<<"年齡"<   }
  }; //好了,我們還需要實現一個超級成員子類和一個項目經理的子類.
  //這是超級成員類
  class Supermember:public Member
  {
  friend class point_list;
  private:
  int sm_documentcount;//提交的文檔數
  int sm_codecount;//提交的代碼段數
  public:
  Supermember(char *sn,char *nm,char *pwd,char *em,char *gd,double ag,int dc,int cc):Member(sn,nm,pwd,gd,ag)
  {
  sm_documnetcount=0;
  sm_codecount=0;
  }
  Spupermember():Member()
  {
  sm_documentcount=0;
  sm_codecount=0;
  }
  void fill_documentcount(int smdc)
  {
  sm_documentcount=smdc;
  }
  void fill_codecount(int smcc)
  {
  sm_codecount=smcc;
  } void addnew()
  {
  pointer=this;
  }
  void display()
  {
  Member::display()
  cout<<"提交文章數:"<   cout<<"提交代碼段數"<   }
  }; //實現友元類
  class point_list
  {
  private:
  Personnel *location;
  public:
  point_list()
  {
  location=0;
  }
  void print();
  void insert(Personnel *node);
  void delete(char *serial_number);
  }
  //顯示鏈表
  void point_list::print()
  {
  Personnel *ps=location;
  while(ps!=0)
  {
  ps->display();
  ps=ps->next_link;
  }
  }
  //插入鏈表
  void point_list::insert(Personnel *node)
  {
  Personnel *current_node=location;
  Personnel *previous_node=0;
  while(current_node!=0 && (strcmp(current_node->name,node->name<0)
  {
  previous_node=current_node;
  current_node=current_node->next_link;
  }
  node->addnew()
  node->pointer->next_link=current_node;
  if(previous_node==0)
  location=node->pointer;
  else
  previous_node->next_link=node->pointer;
  } //從鏈表中刪除
  void point_list::delete(char *serial_number)
  {
  Personnel *current_node=location;
  Personnel *previous_node=0;
  while(current_node!=0 && strcmp(current_node->serial_number,serial_number)!=0)
  {
  previous_node=current_node;
  current_node=current_node->next_link;
  }
  if(current_node !=0 && previous_node==0)
  
   {
  location=current_node->next_link;
  }
  else if(current_node !=0 && previous_node!=0)
  {
  previous_node->next_link=current_node->next_link;
  }
  } //這是主函數,我們顯式的增加3個Supermember信息,然後在通過編號刪除一個
  //我們沒有從成員再派生出治理成員,所以沒有辦法演示它,但我們可以看出要實現它並不難
  //注重:此程序沒有經過驗證,也許會有BUG.
  main()
  {
  point_list pl;
  Supermember sm1("000000000000001","雷神","123456","[email protected]","男",29.9,10,10);
  Supermember sm1("000000000000002","木一","234567","[email protected]","男",26.5,20,5);
  Supermember sm1("000000000000003","落葉夏日","345678","[email protected]","男",24.8,5,15);
  //假如我們還派生了治理人員,可能的方式如下:
  //Managemember mm1("000000000000004","ADMIN","888888","[email protected]","男",30,5,15,......); //下面是將上面的3個人員信息加到鏈表中
  pl.insert(&sm1);
  pl.insert(&sm2);
  pl.insert(&sm3);
  //對應治理人員的 pl.insert(&mm1); //下面是顯示他們
  //下面是顯示人員列表
  pl.print(); //下面是刪除一個人員信息
  pl.delete("000000000000001");
  //我們再顯示一次看看.
  cout<<" 刪除後的列表: ";
  pl.print();
  }   程序沒有上機驗證,在我的腦子裡運行了一下,我想輸出結果應該是這樣的: 編號:000000000001
  名稱:雷神
  口令:123456
  電子郵件:[email protected]
  性別:男
  年齡:29.9
  提交文章數:10
  提交代碼數:10 編號:000000000002
  名稱:木一
  口令:234567
  電子郵件:[email protected]
  性別:男
  年齡:26.5
  提交文章數:20
  提交代碼數:5 編號:000000000003
  名稱:落葉夏日
  口令:345678
  電子郵件:[email protected]
  性別:男
  年齡:24.8
  提交文章數:5
  提交代碼數:15 刪除後的列表: 編號:000000000002
  名稱:木一
  口令:234567
  電子郵件:[email protected]
  性別:男
  年齡:26.5
  提交文章數:20
  提交代碼數:5 編號:000000000003
  名稱:落葉夏日
  口令:345678
  電子郵件:[email protected]
  性別:男
  年齡:24.8
  提交文章數:5
  提交代碼數:15   通過上面的例子,我想我們能夠理解對象模型的給我們帶來的好處,我們用了大量的指針和引用,來完成多態的特性.和書上的資料庫的例子不同,我們多了一層,那是因為我考慮人員可能是匿名,也可能是注冊的,所以為了區別他們,用了兩層來完成接口,然後所有注冊的正式成員才都由Member類派生出不同的權限的人員,例如超級成員和治理人員.   最後用書上的一段話總結一下吧.P34
  
  總而言之,多態是一種威力強大的設計機制,答應你繼續一個抽象的public接口之後,封裝相關的類型,需要付出的代價就是額外的間接性--不論是在內存的獲得,或是在類的決斷上,C++通過class的pointer和references來支持多態,這種程序風格就稱為"面向對象".
   更多內容請看C/C++技術專題專題,或
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved