C++ Non-Public Inheritance

 今天同事聊起C++的非公有繼承,發現自己知識又有些模糊了。晚上回來Demo溫習一下

Basic Rule:公有繼承用於接口繼承,反映"is-a"關係;非公有繼承用於方法繼承實現和方法封裝性控制。

引CSDN一段關於非公有繼承使用情景的說明:

私有繼承:

 

第一個規則:和公有繼承相反,如果兩個類之間的繼承關係爲私有,編譯器一般不會將派生類對象轉換成基類對象。

第二個規則: 從私有基類繼承而來的成員都成爲了派生類的私有成員,即使它們在基類中是保護或公有成員。私有繼承的含義:私有繼承意味着 "用...來實現"。如果使類D私有繼承於類B,這樣做是因爲你想利用類B中已經存在的某些代碼,而不是因爲類型B的對象和類型D的對象之間有什麼概念上的關係。因而,私有繼承純粹是一種實現技術。私有繼承意味着只是繼承實現,接口會被忽略。如果D私有繼承於B,就是說D對象在實現中用到了B對象,僅此而已。私有繼承在軟件 "設計" 過程中毫無意義,只是在軟件 "實現" 時纔有用。

私有繼承控制實現的一個例子:

  1. class Uncopyable { 
  2. protected:                                   // allow construction 
  3.   Uncopyable() {}                            // and destruction of 
  4.   ~Uncopyable() {}                           // derived objects... 
  5.  
  6. private
  7.   Uncopyable(const Uncopyable&);             // ...but prevent copying 
  8.   Uncopyable& operator=(const Uncopyable&); 
  9. }; 
  10.  
  11. class HomeForSale: private Uncopyable {      // class no longer 
  12.   ...                                        // declares copy ctor or 
  13. };   

 

上面的禁止Copy/Assignment Constructor當然也可以使用下面方法實現:

  1. // A macro to disallow the copy constructor and operator= functions 
  2. // This should be used in the private: declarations for a class 
  3. #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 
  4.   TypeName(const TypeName&);               \ 
  5.   TypeName& operator=(const TypeName&) 
  6.  
  7. class Foo { 
  8.  public
  9.   Foo(int f); 
  10.   ~Foo(); 
  11.  
  12.  private
  13.   DISALLOW_COPY_AND_ASSIGN(Foo); 
  14. }; 

最後附上一段陽春的Demo Code參考:

ClassDemo.h

  1. class ClassDemo 
  2. public
  3.     ClassDemo(void); 
  4.     ~ClassDemo(void); 
  5.  
  6.     void Dump(void); 
  7.     virtual void VDump(void); 
  8.  
  9. protected
  10.     void PDump(void); 
  11.  
  12. private
  13.     void PRDump(void); 
  14. }; 
  15.  
  16. class ClassD1 : private ClassDemo 
  17. public
  18.     ClassD1(void){} 
  19.     ~ClassD1(void){} 
  20.     void Dump(void); 
  21.     virtual void VDump(void); 
  22.  
  23. }; 
  24.  
  25. class ClassD2 : public ClassDemo 
  26. public
  27.     ClassD2(void){} 
  28.     ~ClassD2(void){} 
  29.     void Dump(void); 
  30.     virtual void VDump(void); 
  31. }; 

ClassDemo.cpp

  1. #include <iostream> 
  2.  
  3. #include "ClassDemo.h" 
  4.  
  5. ClassDemo::ClassDemo(void
  6.  
  7. ClassDemo::~ClassDemo(void
  8.  
  9. void ClassDemo::Dump() 
  10.     std::cout<<__FUNCTION__<<std::endl; 
  11.  
  12. void ClassDemo::VDump() 
  13.     std::cout<<__FUNCTION__<<std::endl; 
  14.  
  15. void ClassDemo::PDump() 
  16.     std::cout<<__FUNCTION__<<std::endl; 
  17.  
  18. void ClassDemo::PRDump() 
  19.     std::cout<<__FUNCTION__<<std::endl; 
  20.  
  21. void ClassD1::Dump() 
  22.     //this->PRDump(); //error C2248: cannot access private member 
  23.     this->PDump(); 
  24.     std::cout<<__FUNCTION__<<std::endl; 
  25.  
  26. void ClassD1::VDump() 
  27.     std::cout<<__FUNCTION__<<std::endl; 
  28.  
  29. void ClassD2::Dump() 
  30.     this->PDump(); 
  31.     std::cout<<__FUNCTION__<<std::endl; 
  32.  
  33. void ClassD2::VDump() 
  34.     std::cout<<__FUNCTION__<<std::endl; 

main.cpp

  1. ClassDemo *p_demo1 = new ClassDemo(); 
  2. //ClassDemo *p_demo2 = new ClassD1();//error C2243: 'type cast' 
  3. ClassD1 d1; 
  4. ClassDemo *p_demo3 = new ClassD2(); 
  5.  
  6. p_demo1->Dump();//base 
  7. p_demo1->VDump();//base 
  8. //p_demo2->Dump();//base 
  9. //p_demo2->VDump();//D1 
  10. d1.Dump(); 
  11. d1.VDump(); 
  12. p_demo3->Dump();//base 
  13. p_demo3->VDump();//D2 
  14.  
  15. delete p_demo1; 
  16. //delete p_demo2; 
  17. delete p_demo3; 

Result:

P.S. 抽空該溫習一下Effective C++啦,囧

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