• C++之虚拟继承


    定义:  
      class   B  
      {  
      private:  
              B()  
              {  
              }  
      friend   class   A;  
      };  
      将导致B无法被除A以外的其它任何class直接继承以后实例化,也就是说,在上面这个定义的基础上,如果你再定义:  
              class   C:public   B{};  
      将导致编译能够通过,但是无法实例化C(那当然也没用了,所以间接实现了一个无法继承的类B),但是因为A是B的友元,所以能够进入B的private区域,所以如果定义:  
              class   A:public   B{};  
      能够实例化A.  
      但是这样定义还有一个漏洞,如果在A普通public继承B的基础上再定义:  
              class   D:public   A{};  
      你会发现D也是可以实例化的,那么相当于间接public继承了B。这显然不是我们想要的,所以,正确的做法是(完整代码):  
      class   A;  
      class   B  
      {  
      private:  
              B()  
              {  
              }  
      friend   class   A;  
      };  
      class   A:virtual   public   B{};   //A   is   the   one   we're   looking   for  
      也就是说要做到三步:  
      1)将你B的相关构造函数放入private区域  
      2)声明子类A为B的友元  
      3)定义A为virtual   public继承B  
      这样创建的代码的效果是:  
      B不能被继承也不能被实例化  
      A可以被实例化,但是不能被继承 

    ====================================  
      确切地说,A可以被继承,但是继承了A的类不能被实例化(那这个类也就没用了)。假设有  
            class   E:public   A{};  
      则实例化E时:  
            E   e;  
      系统将报告无法进入B的私有成员声明而无法通过编译。  
      这是因为   A是   virtual   继承   B的,所以,E再继承A的时候,需要由E去调用B的构造函数,但是E不是B的友元,所以无法编译通过  
      但是如果A不是virtual继承B的,那么E再继承A时,构造函数的调用情况是E调用父类A的构造函数,A再调用A的父类B的构造函数,而A是其父类B的友元,所以这一串调用能够顺利进行。

  • 相关阅读:
    机器学习中的正则化问题(2)——理解正则化
    详解 Python 中的下划线命名规则
    编程面试的算法概念汇总
    group by多字段查询解决礼物统计
    一分钟学会Spring Boot多环境配置切换
    Maven 多模块父子工程 (含Spring Boot示例)
    第1章 Spring Cloud 构建微服务架构(一)服务注册与发现
    第3章 Spring Boot 入门指南
    第5章 Spring Boot 功能
    第4章 CentOS软件安装
  • 原文地址:https://www.cnblogs.com/whyandinside/p/1622654.html
Copyright © 2020-2023  润新知