今天同事聊起C++的非公有继承,发现自己知识又有些模糊了。晚上回来Demo温习一下
Basic Rule:公有继承用于接口继承,反映"is-a"关系;非公有继承用于方法继承实现和方法封装性控制。
引CSDN一段关于非公有继承使用情景的说明:
私有继承:
第一个规则:和公有继承相反,如果两个类之间的继承关系为私有,编译器一般不会将派生类对象转换成基类对象。
第二个规则: 从私有基类继承而来的成员都成为了派生类的私有成员,即使它们在基类中是保护或公有成员。私有继承的含义:私有继承意味着 "用...来实现"。如果使类D私有继承于类B,这样做是因为你想利用类B中已经存在的某些代码,而不是因为类型B的对象和类型D的对象之间有什么概念上的关系。因而,私有继承纯粹是一种实现技术。私有继承意味着只是继承实现,接口会被忽略。如果D私有继承于B,就是说D对象在实现中用到了B对象,仅此而已。私有继承在软件 "设计" 过程中毫无意义,只是在软件 "实现" 时才有用。
私有继承控制实现的一个例子:
- 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.h
- 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++啦,囧