今天同事聊起C++的非公有繼承,發現本身知識又有些模糊了。晚上回來Demo溫習一下ios
Basic Rule:公有繼承用於接口繼承,反映"is-a"關係;非公有繼承用於方法繼承實現和方法封裝性控制。ide
引CSDN一段關於非公有繼承使用情景的說明:this
私有繼承:
spa
第一個規則:和公有繼承相反,若是兩個類之間的繼承關係爲私有,編譯器通常不會將派生類對象轉換成基類對象。設計
第二個規則: 從私有基類繼承而來的成員都成爲了派生類的私有成員,即便它們在基類中是保護或公有成員。私有繼承的含義:私有繼承意味着 "用...來實現"。若是使類D私有繼承於類B,這樣作是由於你想利用類B中已經存在的某些代碼,而不是由於類型B的對象和類型D的對象之間有什麼概念上的關係。於是,私有繼承純粹是一種實現技術。私有繼承意味着只是繼承實現,接口會被忽略。若是D私有繼承於B,就是說D對象在實現中用到了B對象,僅此而已。私有繼承在軟件 "設計" 過程當中毫無心義,只是在軟件 "實現" 時纔有用。對象
私有繼承控制實現的一個例子:blog
- class Uncopyable {
- protected: // allow construction
- Uncopyable() {} // and destruction of
- ~Uncopyable() {} // derived objects...
- private:
- Uncopyable(const Uncopyable&); // ...but prevent copying
- Uncopyable& operator=(const Uncopyable&);
- };
- class HomeForSale: private Uncopyable { // class no longer
- ... // declares copy ctor or
- };
上面的禁止Copy/Assignment Constructor固然也能夠使用下面方法實現:繼承
- // A macro to disallow the copy constructor and operator= functions
- // This should be used in the private: declarations for a class
- #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
- TypeName(const TypeName&); \
- TypeName& operator=(const TypeName&)
- class Foo {
- public:
- Foo(int f);
- ~Foo();
- private:
- DISALLOW_COPY_AND_ASSIGN(Foo);
- };
最後附上一段陽春的Demo Code參考:接口
ClassDemo.hget
- class ClassDemo
- {
- public:
- ClassDemo(void);
- ~ClassDemo(void);
- void Dump(void);
- virtual void VDump(void);
- protected:
- void PDump(void);
- private:
- void PRDump(void);
- };
- class ClassD1 : private ClassDemo
- {
- public:
- ClassD1(void){}
- ~ClassD1(void){}
- void Dump(void);
- virtual void VDump(void);
- };
- class ClassD2 : public ClassDemo
- {
- public:
- ClassD2(void){}
- ~ClassD2(void){}
- void Dump(void);
- virtual void VDump(void);
- };
ClassDemo.cpp
- #include <iostream>
- #include "ClassDemo.h"
- ClassDemo::ClassDemo(void)
- {
- }
- ClassDemo::~ClassDemo(void)
- {
- }
- void ClassDemo::Dump()
- {
- std::cout<<__FUNCTION__<<std::endl;
- }
- void ClassDemo::VDump()
- {
- std::cout<<__FUNCTION__<<std::endl;
- }
- void ClassDemo::PDump()
- {
- std::cout<<__FUNCTION__<<std::endl;
- }
- void ClassDemo::PRDump()
- {
- std::cout<<__FUNCTION__<<std::endl;
- }
- void ClassD1::Dump()
- {
- //this->PRDump(); //error C2248: cannot access private member
- this->PDump();
- std::cout<<__FUNCTION__<<std::endl;
- }
- void ClassD1::VDump()
- {
- std::cout<<__FUNCTION__<<std::endl;
- }
- void ClassD2::Dump()
- {
- this->PDump();
- std::cout<<__FUNCTION__<<std::endl;
- }
- void ClassD2::VDump()
- {
- std::cout<<__FUNCTION__<<std::endl;
- }
main.cpp
- ClassDemo *p_demo1 = new ClassDemo();
- //ClassDemo *p_demo2 = new ClassD1();//error C2243: 'type cast'
- ClassD1 d1;
- ClassDemo *p_demo3 = new ClassD2();
- p_demo1->Dump();//base
- p_demo1->VDump();//base
- //p_demo2->Dump();//base
- //p_demo2->VDump();//D1
- d1.Dump();
- d1.VDump();
- p_demo3->Dump();//base
- p_demo3->VDump();//D2
- delete p_demo1;
- //delete p_demo2;
- delete p_demo3;
Result:
P.S. 抽空該溫習一下Effective C++啦,囧