首页 > 其他分享 >类和对象-继承

类和对象-继承

时间:2023-02-21 23:01:39浏览次数:28  
标签:继承 +--- public 对象 int 父类 class

继承是面向对象三大特性之一 定义类时,下级别的成员除了拥有上一级的共性,还有自己的特性,就可以考虑使用继承的技术,减少代码的重复

继承的基本语法

语法:class 子类 : 继承方式 父类

  • 子类也被成为派生类
  • 父类也被称为基类
class A
{
public:
    string name;
};
class B :public A
{
public:
    int age;
};
int main()
{
    B b;
    b.name = "张三";
    b.age = 10;
    cout << b.name << b.age << endl;
    return 0;
}

继承方式

继承方式一共有三种:

  • 公共继承
    • 访问权限不变
  • 保护继承
    • 除私有内容外,都变为保护权限
  • 私有继承
    • 除私有内容外,都变为私有权限

父类中的私有内容,三种继承方法都无法访问

class A
{
public:
    int a;
protected:
    int b;
private:
    int c;
};
class B :public A//公共继承
{

};
class C :protected A//保护继承
{

};
class D :private A//私有继承
{

};

继承中的对象模型

父类中所有非静态成员属性都会被子类继承下去 父类中私有的成员属性,是被编译器给隐藏了,因此是访问不到,但是确实被继承下去了 利用开发人员命令提示工具查看对象模型:

  1. 跳转盘符:盘符:
  2. 跳转文件路径:cd 具体路径下
  3. 查看命名:dir
  4. 报告单个类的布局:cl /d1 reportSingleClassLayout类名 文件名

文件名可按Tap建自动补齐

class A
{
public:
    int a;
protected:
    int b;
private:
    int c;
};
class B :public A//公共继承
{
    int c;
};
class B size(16):
        +---
 0      | +--- (base class A)
 0      | | a
 4      | | b
 8      | | c
        | +---
12      | c
        +---

继承中构造和析构顺序

先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反

继承同名成员处理方式

子类对象可以直接访问到子类中的同名成员 子类对象加作用域可以访问到父类同名成员 当子类与父类拥有同名的成员函数,子类会隐藏父类中所有同名成员函数,加作用域可以访问到父类中同名函数

class A
{
public:
    void test()
    {
        cout << "A" << endl;
    }
};
class B :public A//公共继承
{
public:
    void test()
    {
        cout << "B" << endl;
    }
};
int main()
{
    B b;
    b.test();
    b.A::test();
    return 0;
}

继承同名静态成员处理方式

静态成员跟非静态成员出现同名,处理方法一致,只不过有两种处理方法:

  • 通过对象.
  • 通过类名::
class A
{
public:
    static string a;
};
class B :public A//公共继承
{
public:
    static string a;
};
//类内声明,类外初始化
string B::a = "B";
string B::A::a = "A";
int main()
{
    //通过对象访问
    B b;
    cout << b.a << endl;
    cout << b.A::a << endl;
    //通过类名访问
    cout << B::a << endl;
    //第一个::表示通过类名方式访问,第二个::代表访问父类作用域下
    cout << B::A::a << endl;
    return 0;
}

多继承语法

C++允许一个类继承多个类 语法:class 子类 : 继承方式 父类1 , 继承方式 父类2... 多继承可能会引发父类中有同名成员出现,需要加作用域区分 C++实际开发中不建议用多继承

class A
{
public:
    int a;
};
class B
{
public:
    int a;
};
class C :public A, public B
{
};
int main()
{
    C c;
    c.A::a = 10;
    c.B::a = 20;
    cout << c.A::a << endl;
    cout << c.B::a << endl;
    return 0;
}

菱形继承

菱形继承概念:

  • 两个派生类继承同一个基类
  • 又有某个类同时继承这两个派生类
  • 这种继承被称为菱形继承,也被称为钻石继承

典型的菱形继承问题: 菱形继承问题:子类继承两份相同的数据,导致资源浪费以及毫无意义

  • 羊继承了动物的数据,驼也继承了动物的数据,当羊驼使用数据时,就会产生二义性
  • 羊驼继承自动物的数据继承了两份,只需要一份就可以

利用虚继承,解决菱形继承的问题:

  • 继承之前,加上关键字virtual变为虚继承
  • 公共的父类被称为虚基类
class A
{
public:
    int a;
};
//A为虚基类
class B :virtual public A{};
class C :virtual public A{};
class D:public B,public C{};
int main()
{
    D d;
    d.a = 10;
    cout << d.a << endl;
    return 0;
}

vbptr虚基类指针:

  • v-virtual
  • b-base
  • ptr-pointer

虚基类指针指向vbtable虚基类表

  • 实际继承了两个指针,通过偏移量,找到那份唯一的数据
class D size(24):
        +---
 0      | +--- (base class B)
 0      | | {vbptr}
        | | <alignment member> (size=4)
        | +---
 8      | +--- (base class C)
 8      | | {vbptr}
        | | <alignment member> (size=4)
        | +---
        | <alignment member> (size=4)
        +---
        +--- (virtual base A)
16      | a
        +---

D::$vbtable@B@:
 0      | 0
 1      | 16 (Dd(B+0)A)

D::$vbtable@C@:
 0      | 0
 1      | 8 (Dd(C+0)A)
vbi:       class  offset o.vbptr  o.vbte fVtorDisp
               A      16       0       4 0

标签:继承,+---,public,对象,int,父类,class
From: https://blog.51cto.com/wushf/6077114

相关文章

  • 面向对象
    三大特性封装封装是把客观事物抽象成类,并且把自己的属性和方法让可信的类或对象操作,对不可性的隐藏。继承继承是指这样一种能力:它可以使用现有类的所有功能,并在无......
  • 【Spring AOP】【七】Spring AOP源码解析-代理对象执行过程
    1 前言不知道你现在清晰了没,我们一路从AOP的基础概念,到AOP配置的解析,到AOP在Bean的生命周期的切入时机以及创建代理的过程一步步走下来,脑瓜还清晰不,那我们是不是就该到......
  • 多个线程操作一个对象
    packagecom.Java;//多个线程操作同一个对象//抢火车票例子//发现问题多个线程抢夺同个资源的情况下线程不安全数据紊乱publicclassTestThread4implementsRunnable......
  • 继承Thread开启多线程下载图片(不推荐,java的单一继承性)
    packagecom.Java;importorg.apache.commons.io.FileUtils;importjava.io.File;importjava.io.IOException;importjava.net.URL;//练习多线程Thread,实现多线程下载图片......
  • DJango-ORM根据primary_value获取对应的类对象
    @classmethoddefget_obj_by_primary_value(cls,primary_value=None):primary_key=Nonefields=cls._meta.get_fields()forobjinfields:ifob......
  • 深入理解JavaScript对象
    前言在JavaScript中,对象是一种非常常见的数据类型,几乎每个程序员都会在日常工作中频繁地使用对象。在本篇文章中,我们将深入了解JavaScript对象的一些基本概念和一些高......
  • js两个对象的比较
    constequals=(a,b)=>{if(a===b)returntrue;if(ainstanceofDate&&binstanceofDate){returna.getTime()===b.getTime()}if(!a||!b||(ty......
  • Jackson_java对象转json 注解
    Java对象转换JSON1使用步骤1导入jackson的相关jar包2创建Jackson核心对象ObjectMapper3调用ObjectMapper的相关方法进行转换转......
  • 对象定义-解构-枚举属性遍历以及对象内函数
    属性名表达式定义对象的属性有两种方式1、直接使用标识符作为属性名obj.name2、以表达式作为属性名obj['a'+'b']=10letobj={}obj.name='孙悟空'//孙悟空......
  • JQuery_快速入门与JQuery对象和JS对象区别与转换
    JQuery_快速入门1.概念2.快速入门1.步骤:1.下载JQuery......