zoukankan      html  css  js  c++  java
  • 【基础复习】七:继承与接口


    覆盖

    面试题

    • 构造函数从最初始的基类开始构造,各个类的同名变量没有形成覆盖,都是单独的变量
    • 就近调用。如果派生类没有定义相关接口,父辈存在相关接口则优先调用父辈接口,如果父辈也不存在相关接口则调用祖父辈接口。
    • 派生类的虚函数会覆盖基类的虚函数,因此不管是用什么指针指向内存中的派生类,调用的都是派生类自己的虚函数。

    私有继承

    • 私有继承使对象不能被派生类的子类访问
    • 如果不指定public,c++默认的是私有继承
    • 子类只能继承父类的protected和public
    • 在无继承的类中,protected和private是没有区别的
    • 一个私有的或保护的派生类不是子类,因为非公共的派生类不能做基类能做的所有的事
    • 继承和多重继承一般考虑的是公共继承

    • 公有继承。在公有继承时,基类的公有成员和保护成员在派生类中保持原来状态。派生类的对象可以访问基类中的公有成员,派生类的成员函数可以访问基类中的公有成员和保护成员。
    • 私有继承。在私有继承时,基类的公有成员和保护成员在派生类中变成私有成员。基类的成员只能由直接派生类访问,而无法再往下继承。
    • 保护继承。在保护继承时,基类的公有成员和保护成员在派生类中变成保护成员。基类的成员不能被派生类的子类的对象所访问,但可以被派生类的子类访问。

    虚函数继承和虚继承

    • 当一个类中有虚函数时,每个对象里有虚表指针,指向虚表,虚表里存放了虚函数的地址。虚函数表是顺序存放虚函数地址的,不需要用到链表(link list)。

    • (虚)继承是包含父类的所有内容后,再加上自己定义的内容

    • 关键字virtual告诉编译器不应该完成早绑定,而是应当自动安装实现晚绑定所必需的所有机制。当对derived对象通过基类base指针调用函数fun()时,我们将得到恰当的函数

    • 利用虚函数,这个对象的合适的函数就能被调用,哪怕编译器还不知道这个对象的特定类型。

    • 什么是虚继承?它与一般继承有什么不同?它有什么用?它有什么用?
      答:虚拟继承是多重继承中特有的概念,虚拟基类是为解决多重继承而出现的。当一个派生类的两个父类都继承于同一个祖先类时,使父类虚继承于一个祖先类,那么这个派生类的内存中就只有一个祖先类。虚函数继承和虚继承是完全不同的概念,不要在面试中混淆

    • 为什么虚函数效率低?
      答:因为虚函数需要一次间接的寻址,而一般的函数可以在编译时定位到函数的地址,虚函数(动态类型调用)是要根据某个指针定位到函数的地址。多增加了一个过程,效率肯定会低一些,但带来了运行时的多态。

    多重继承

    • 多重继承的优点和缺陷
      • 大多数系统中类层次往往都有一个公共的基类,这样的结构使用多重继承,稍有不慎会出现菱形继承,这样的继承方式会使得类的访问结构非常复杂。可以用虚继承等其他方法解决。
      • 多重继承在面向对象理论中不是必要的,它可以通过单继承和复合结构来取代。
      • c++中不定义属性的抽象类就相当于接口interface。

    组合

    若在逻辑上,A是B的一部分,则不允许B从A派生,而是要用A和其他东西组合出B。
    如眼睛、鼻子、嘴巴、耳朵是头的一部分,使用组合代码如下:

    #include<iostream>
    #include<string>
    using namespace std;
    
    class eye
    {
      public:
        void look(){}
    };
    
    class nose {
      public:
        void smell(){}
    };
    
    class mouth
    {
      public:
        void eat(){}
    };
    
    class ear
    {
      public:
        void listen() {}
    };
    
    class head {
      public:
        void look() {m_eye.look();}
        void smell() {m_nose.smell();}
        void eat() {m_mouth.eat();}
        void listen() {m_ear.listen();}
      private:
        eye m_eye;
        nose m_nose;
        mouth m_mouth;
        ear m_ear;
    };
    
    int main() {
        head m_head;
        m_head.look();
    }
    

    纯虚函数

    • 类中有纯虚函数virtual void Draw()=0时,这个类是不能实例化成一个对象的

    • C++如何阻止一个类被实例化?
      使用抽象类,或者构造函数被声明成private

    • 构造函数被声明成private会阻止编译器生成默认的拷贝构造函数吗?
      如果我们没有定义拷贝构造函数,编译器就会为我们合成一个。与合成默认构造函数不同,即使我们定义了其他构造函数,也会合成拷贝构造函数。

    运算符重载和RTTI


    from《程序员面试宝典》



  • 相关阅读:
    .NetCore~框架版本号不同引起dotnet不能run它
    Linux~centos上安装.netcore,HelloWorld归来!
    Lind.DDD.Utils.HttpHelper里静态对象引出的Http超时问题
    [置顶] C++ Pirate: Lambda vs Bind
    如何成为CSDN博客专家
    MFC下的日历表
    世界上最便宜的10张防癌处方
    android权限大全
    应用程序管理集
    谢希仁《计算机网络》第五版---第四章
  • 原文地址:https://www.cnblogs.com/zengyh-1900/p/5247559.html
Copyright © 2011-2022 走看看