C++ NonPublic Inheritance

今天同事聊起C++的非公有继承,发现自己知识又有些模糊了。晚上回来Demo温习一下


    		    C++ NonPublic Inheritance

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. private:
  6. Uncopyable(const Uncopyable&); // ...but prevent copying
  7. Uncopyable& operator=(const Uncopyable&);
  8. };
  9. class HomeForSale: private Uncopyable { // class no longer
  10. ... // declares copy ctor or
  11. };

上面的禁止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. class Foo {
  7. public:
  8. Foo(int f);
  9. ~Foo();
  10. private:
  11. DISALLOW_COPY_AND_ASSIGN(Foo);
  12. };

最后附上一段阳春的Demo Code参考:

ClassDemo.h

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

ClassDemo.cpp

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

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. p_demo1->Dump();//base
  6. p_demo1->VDump();//base
  7. //p_demo2->Dump();//base
  8. //p_demo2->VDump();//D1
  9. d1.Dump();
  10. d1.VDump();
  11. p_demo3->Dump();//base
  12. p_demo3->VDump();//D2
  13. delete p_demo1;
  14. //delete p_demo2;
  15. delete p_demo3;

Result:




    		    C++ NonPublic Inheritance

P.S. 抽空该温习一下Effective C++啦,囧

更多相关文章
一周排行
  • 


    		    一次腳本和crond引發的系統故障
    今天早上来到公司,第一件事就是打开监控看下情况.一看吓死人,几乎所有的服务器负载全部跑到1 ...
  • MySQL提供的group_concat函数可以拼接某个字段值成字符串,如 select group_concat(user_name) from sys_user,默认的分隔符是 逗号,即"," ...
  • 7. 备份和恢复 本章主要会介绍: 1.备份的类型:逻辑备份,物理备份,全备和增量4种 2.创建备份的方法 3.还原方法,包括还原到时间点 4.备份计划,压缩和加密 5.表维护,恢复损坏的表 7. 备份和恢复...
  • 初始目标:通过linux脚本读取redisserver的某个键值 脚本如下: ########################################## # example1: ./getredis.sh
  • 


    		    用mdadm管理軟件RAID
    用mdadm管理软件RAID mdadm使用的也是md驱动,由于其拥有多种模式,而且单一工 ...
  • 


    		    IE8安全設定For XenApp
    有些客户对安全性要求比较高,发布IE后希望相关的安全设定,比如隐藏地址栏.工具栏.收藏夹等 ...
  • 一.默认状态下const对象仅在文件内有效,可以使用extern关键字设置所有文件都可以访问. 二.对常量的引用:const int ci = 1024: const int &r = ci; 三.临时量(临 ...
  • 


    		    Windows Server 2012 存儲 (五) 支持SQL over SMB
    通过 SMB 3.0,Windows Server 2012 提供了一种新方式来存储和访问
  • 一个DBA同事昨天在执行一个命令行工具的时候发现程序hang住,问题挺有意思,值得记录下. 首先用pstack看了下程序的调用栈,这是个多线程程序,pstack结果看到几乎所有的线程都等在write调用上.如下是pt
  • 


    		    10SCVMM2012之庫伺服器
    4.5.库服务器 4.5.1.添加库服务器 默认情况下,SCVMM服务器安装完成后,也作为