c++ base-面向对象特性

    xiaoxiao2025-04-08  15

    1.封装、继承、多态

    a) 封装:【c++中的具体表现就是把一个具体的事物封装成类】,并用privateprotectedprivate等关键字修饰类成员,隐藏细节,使代码模快化

    b) 继承:【使用现有类的所有功能】,可以分为单一继承和多重继承。继承方式分为publicprotectedprivateClass默认private继承,struct默认public继承。(一般析构函数都会定义为虚函数,若不然析构时只会调用base的析构函数而不调用derived的析构函数)(封装和继承都是为了【代码重用】)

    c) 多态:【允许将子类类型的指针赋值给父类类型的指针】。实现多态的方式有两种,覆盖(重写)和重载。(父类类型作为参数类型,可以接受来自不同子类的参数,【接口重用】,方便多了)

    2.C++封装

    a) publicprotectprivate

    i. 访问分为:被【类成员函数访问】和被【类对象访问】,只有public才能被对象访问

    ii. Public:【可以被该类中的函数、子类的函数、以及友元函数访问】+可以被该类的对象访问】

    iii. Protect:【可以被该类的函数、子类的函数、以及友元函数访问】

    iv. Private:【可以被该类的函数、友元函数访问】

    3.C++继承

    a) 公有、私有、保护继承

    i. publicprotectprivate

    1. 访问分为:被【类成员函数访问】和被【类对象访问】,只有public才能被对象访问

    2. Public:【可以被该类中的函数、子类的函数、以及友元函数访问】+可以被该类的对象访问】

    3. Protect:【可以被该类的函数、子类的函数、以及友元函数访问】

    4. Private:【可以被该类的函数、友元函数访问】

    ii. publicprotectprivate继承

    1. 继承改变的是基类中的成员在作为派生类成员时,成员的封装属性。即派生类继承了基类,基类的成员在派生类中变成了什么类型的成员,所以看继承后,派生类、对象、友元函数对基类成员的访问权限,只要看某种继承后,基类成员在派生类中的类型就行

     

    Public

    Protected

    Private

    Public继承

    Public

    Protected

    不可见

    Protect继承

    Protected

    Protected

    不可见

    Private继承

    Private

    Private

    不可见

    2. 那么对于基类成员对象可见与否,只有公有继承的public成员才对基类和基类的派生类可见(所访问);不论是哪种继承,对于基类的非private成员对于派生类的都是可见的。

    b) 虚继承

    i. 虚继承是为了在多继承的时候避免引发歧义而使用的(避免菱形继承),如有基类AA中有成员aB继承了AC也继承了A,当D继承BC时就会有歧义了,2a。所以要使用虚继承来避免重复拷贝。通俗的讲虚继承是为了节约内存的。

    Class A{};

    Class B:virtual public A{};

    Class C:virtual public A{};

    Class D:public B,public C{};

    c) 多重继承

    4.c++多态

    a) 实现多态的机制

    i. c++中实现多态的方式有两种:覆盖和重载

    1. 覆盖是指:子类重新定义父类的虚函数的做法

    2. 重载是指:允许存在多个同名函数,而这些函数的参数表,返回值不同

    3. 既然重载的函数返回值或参数表不同,那么在编译期时,编译器就能确定调用的是哪个同名函数,那么它的绑定就发生在编译器,是【静态】的;当子类重新定义了父类虚函数后,父类指针根据赋给它的不同子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期是无法确定的(调用的子类的虚函数地址无法给出),因此这样的函数地址是在运行期绑定的,是【动态】的

    b) 类成员覆盖/重写/虚函数继承

    i. 只有在父类成员方法的前面用virtual关键字修饰,子类才会覆盖父类的方法。从而实现多态

    ii. 成员函数的覆盖:子类对父类的成员函数的覆盖,必须函数名称一致,参数一致,返回值一致;成员变量的覆盖:子类覆盖的仅仅是继承来的那个成员变量,并不改变原来父类中的变量值(即:调用父类中涉及到父类变量的函数,父类使用的是父类的值)。

    iii. 【构造函数从基类开始构造】,【各个类的同名变量没有形成覆盖】,都是单独的变量。【子类调用就近原则】,如果自己存在相关接口则优先调用,自己没有向父类找,父类没有向祖父找。 

    c) 类成员的重载

    i. 函数名相同,参数表和返回值类型不同,在编译期绑定,是静态的

    d) 多态的调用过程

    i. 使用对象类型为【基类类型】引用或者指针进行函数调用,首先在基类中查找一个能与待调用函数实参类型相同的函数,如果找不到则调用错误。

    ii. 如果找到,看该函数是否是虚函数。如果不是虚函数,【那么即使运行时绑定的是继承类的对象,那么还是调用基类中的函数】;如果是虚函数,而且继承类中有相应的覆盖,那么就会调用指针实际绑定的子类对象的覆盖函数。

    转载请注明原文地址: https://ju.6miu.com/read-1297870.html
    最新回复(0)