c++继承详解之一——继承的三种方式、派生类的对象模型

2023-05-16

  C++是OOP(Object Oriented Programming)语言,即面向对象编程语言。OOP的核心思想就是数据抽象(类的设计),继承和动态绑定。

  类展现了C++的封装特性,即将具体的实现过程隐藏,只向外暴露公有接口,即数据抽象,通过数据抽象,我们可以将类的接口与实现分离,(即设计类)。
  与C相比,类可以通过相互间的继承和派生形成层次结构,派生类继承了基类的数据结构和方法 [编译时]。
  使用继承,可以定义相似的类型并对其相似关系建模。
  继承体现了OOP中事物的普遍性和特殊性。
  OOP强调软件的可重用性(software reuseablility).C++提供类的继承机制,解决了软件重用的问题。
  而动态绑定即体现了多态的思想,在此不赘述,以后会专门写一篇关于多态的文章。

一、继承简介

  通过继承机制,可以利用已有的数据类型来定义新的数据类型。所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。
  我们称已存在的用来派生新类的类为基类,又称为父类。由已存在的类派生出的新类称为派生类,又称为子类。
  基类负责定义所有类共同拥有的成员,而每个派生类定义各自特有的成员。
  派生类必须通过使用类派生列表明确指出它是从哪个类继承而来,并说明它是公有继承,保护继承还是私有继承。
下面是继承可以完成的一些操作:

  1. 可以再已有类的基础上添加功能。
  2. 可以给类添加数据。比如说基类马,可以派生一个白马类,在内加入颜色属性:白色
  3. 可以修改类方法的行为。

      当然,以上都可以通过复制修改源代码来完成,但继承机制只需要提供新特性,甚至只看对外接口不用看源码就可以派生出类,添加新特性。
    本文规定Base表示基类名称,Derive表示派生类名称

单继承

类派生列表的格式为:
class Base
{};
class Derive:public Base//公有继承
{};
class Derive2:protected Base //保护继承
{};
class Derive3:private Base//私有继承
{};
//上面的代码中,Derive,Derive2,Derive3都继承自Base基类
//区别就是继承方式不同

类关系图
注意上图的箭头,箭头方向表示继承方向,从派生类指向基类。
派生类是基类的具体化,而基类是派生类的抽象。
单继承的定义格式如下:

class<派生类名>:<继承方式><基类名>
{
<派生类新定义成员>
};

  其中,class是关键词,<派生类名>是新定义的一个类的名字,它是从<基类名>中派生的,并且按指定的<继承方式>派生的。
  <继承方式>常使用如下三种关键字给予表示:

  • public 表示公有继承;
  • private 表示私有继承;
  • protected 表示保护继承;

多继承

多继承的定义格式如下:

class<派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
{
    <派生类新定义成员>
};

注意,在多继承时,如果省略继承方式,默认为private

class A
{
    int a;
    void a()
    {}
};
class B
{
    int b;
    void b()
    {}
};
class C :public A, public B//A,B都是公有继承
{
    int c;
    void c()
    {}
};
class C :public A, public B//A,B都是公有继承
{
    int c;
    void c()
    {}
};
class C :public A, B//A为公有继承,B为私有继承
//可以类比定义指针时int *p,b;
    int c;
    void c()
    {}
};

二、派生类的构成

  派生类分为两大部分,一部分是从基类继承而来的成员,如下图data_B,另一部分是在声明派生类是增加的部分,如下图的data_D。

class Base
{
    int data_B;
};
class Derive:public Base//用公有继承先举例
{
    int data_D;
};

派生类的构成
构造一个派生类需要做以下三部分工作:

  1. 从基类接受成员。

    派生类会把基类的全部成员(不包括构造函数和析构函数)接收过来,不能选择接收其中的一部分。

  2. 调整从基类接受的成员。

      在派生类中可以改变基类成员在派生类中的访问属性,这就是下面我们要将的指定继承方式来实现的。
    如果在派生类中声明了一个与基类成员相同名字的函数,派生类的新成员会覆盖基类的同名成员。

  3. 在声明派生类时增加的成员

多继承时派生类的构成

class A
{
    int a;
    void a()
    {}
};
class B
{
    int b;
    void b()
    {}
};
class C :public A, public B
{
    int c;
    void c()
    {}
};

这里写图片描述

其实多继承派生类的模型与继承列表类的顺序是有关的

class A
{
    int a;
    void a()
    {}
};
class B
{
    int b;
    void b()
    {}
};
class C :public B, public A
{
    int c;
    void c()
    {}
};

此时派生类的模型变为下图:
这里写图片描述

三、public,protected,private三种继承

  派生类可以继承定义在基类中的成员,但是派生类的成员函数不一定有权访问从基类继承而来的成员。
派生类将除了基类的构造函数和析构函数以外的所有成员都继承下来了。

  派生类有权访问哪些成员呢?
  那就是我们下面要说的三种继承方式决定的了

1.公有继承:

公有继承的格式为

class Derive:public Base
//public表示公有继承,如果不写继承方式

class Derive:Base
//默认私有继承

  公有继承时,基类的公用成员和保护成员在派生类中保持原有的访问属性,其私有成员仍为基类私有,即在派生类中不能访问,在类外也不能访问。
  私有成员体现了数据的封装性,如果基类的私有成员可以被派生类所访问,即破坏了基类的封装性,这就会失去C++的一个重要特性。

  大家看下面的代码

class Base
{
public:
    Base(int a = 0,int b = 0,int c = 0)
        :_pub(a)
        , _pro(b)
        , _pri(c)
    {
        cout << "Base()" << endl;
    }
    ~Base()
    {
        cout << "~Base()" << endl;
    }
    int _pub;
protected:
    int _pro;
private:
    int _pri;
};
class Derive :public Base
{
public:
    Derive()
    {}
    ~Derive()
    {}
    void Display()
    {
        cout << "_pri" << _pri << endl;//会报错
        //父类的是私有的
        //相当于在类外访问私有成员
        cout << "_pro" << _pro << endl;
        cout << "_pub" << _pub << endl;

        cout << "d_pri" << d_pri << endl;
        cout << "d_pro" << d_pri << endl;
        cout << "d_pub" << d_pri << endl;
    }
private:
    int d_pri;
protected:
    int d_pro;
public:
    int d_a;
};
int main()
{
    Derive a;
    a.Display();
    //会报错,编译不通过
}

在注释中我写出了运行结果,会报错。

Error   1   error C2248: 'Base::_pri' : cannot access private member declared in class 'Base'   e:\demo\继承\way\project1\project1\source.cpp 34  1   Project1

  为什么派生类不能访问基类的私有成员?
  答:因为派生类和基类是不同的类域,在不同类中访问相当于在类外访问私有成员。
  我们在派生类的成员函数中访问了父类的私有成员,相当于在类外访问私有成员,是错误的。

2.保护继承

  保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。

  对派生类而言,保护成员类似于公有成员,但对于外部而言,保护成员与私有成员类似。
  保护继承——原public,protected属性的成员继承后为protected属性,原private成员仍为private属性

class Base
{
public:
    Base(int a = 0,int b = 0,int c = 0)
        :_pub(a)
        , _pro(b)
        , _pri(c)
    {
        cout << "Base()" << endl;
    }
    ~Base()
    {
        cout << "~Base()" << endl;
    }
    int _pub;
protected:
    int _pro;
private:
    int _pri;
};
class Derive :protected Base
{
public:
    Derive()
    {}
    ~Derive()
    {}
    void Display()
    {
        cout << "_pri" << _pri << endl;//会报错
        //父类的是私有的
        //相当于在类外访问私有成员
        cout << "_pro" << _pro << endl;
        cout << "_pub" << _pub << endl;
        //_pro,_pub均为protected属性,可以类内访问

        cout << "d_pri" << d_pri << endl;
        cout << "d_pro" << d_pri << endl;
        cout << "d_pub" << d_pri << endl;
    }
private:
    int d_pri;
protected:
    int d_pro;
public:
    int d_a;
};
int main()
{
    Derive a;
    a.Display();
    a._pro = 0;
    a._pub = 0;
    //上面两句均会报错,因为_pro,_pub均为protected属性的成员
    //不能在类外访问
}

3.私有继承

  私有继承即所有基类成员均变成派生类的私有成员,基类的私有成员仍然不能在派生类中访问。

class Base
{
public:
    Base(int a = 0,int b = 0,int c = 0)
        :_pub(a)
        , _pro(b)
        , _pri(c)
    {
        cout << "Base()" << endl;
    }
    ~Base()
    {
        cout << "~Base()" << endl;
    }
    int _pub;
protected:
    int _pro;
private:
    int _pri;
};
class Derive :private Base
{
public:
    Derive()
    {}
    ~Derive()
    {}
    void Display()
    {
        cout << "_pri" << _pri << endl;//会报错
        //父类的是私有的
        //相当于在类外访问私有成员
        cout << "_pro" << _pro << endl;
        cout << "_pub" << _pub << endl;
        //_pro,_pub均为protected属性,可以类内访问

        cout << "d_pri" << d_pri << endl;
        cout << "d_pro" << d_pri << endl;
        cout << "d_pub" << d_pri << endl;
    }
private:
    int d_pri;
protected:
    int d_pro;
public:
    int d_a;
};
int main()
{
    Derive a;
    a.Display();
    a._pro = 0;
    a._pub = 0;
    //上面两句均会报错,因为_pro,_pub均为private属性的成员
    //不能在类外访问
}

  三种继承方式都介绍完毕后,肯定会有一个问题,那就是派生类无论怎样都无法访问基类的私有成员,那么我们要想知道私有成员的状态应该怎么办呢?
我们可以在基类定义非私有的show函数,然后在派生类调用它即可

class Base
{
    public:
    Base()
    {

    }

    ~Base()
    {

    }
    void Show()
    {
        cout<<"_pri"<<_pri<<endl;
        cout<<"_pro"<<_pri<<endl;
        cout<<"_pub"<<_pri<<endl;
    }
    private:
    int _pri;
    protected:
    int _pro;
    public:
    int _pub;
};
class Derive:protected Base
{
    public:
    Derive()
    {}
    ~Derive()
    {}
    void Display()
    {
        Show();//即可知道基类所有成员的状态
        //因为show函数是非私有的
        //所以派生类无论是哪种继承方式继承的,都可以调用show函数
        cout<<"d_pri"<<d_pri<<endl;
        cout<<"d_pro"<<d_pri<<endl;
        cout<<"d_pub"<<d_pri<<endl;
    }
    private:
    int d_pri;
    protected:
    int d_pro;
    public:
    int d_a;
};
int main()
{
    Derive a;
    a.Display();
    //运行时,会打印出基类的成员状态
}

四、友元函数、静态成员函数的继承

  相信看完上面的介绍,会对继承有一些了解了。
  那么基类的友元函数能不能被派生类继承呢?

1.友元函数

  答案是:不能!
  友元只是能访问指定类的私有和保护成员的自定义函数,不是被指定类的成员,自然不能继承。
使用友元类时注意:

(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。

  若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3)友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明
注意事项:

1.友元可以访问类的私有成员。
2.友元只能出现在类定义内部,友元声明可以在类中的任何地方,一般放在类定义的开始或结尾。
3.友元可以是普通的非成员函数,或前面定义的其他类的成员函数,或整个类。
4.类必须将重载函数集中每一个希望设为友元的函数都声明为友元。
5.友元关系不能继承,基类的友元对派生类的成员没有特殊的访问权限。如果基类被授予友元关系,则只有基类具有特殊的访问权限。该基类的派生类不能访问授予友元关系的类。

class Base
{
    friend void fun();
public:
    Base(int data = 0)
        :b(data)
    {
        cout << "Base()" << endl;
    }
    ~Base()
    {
        cout << "~Base()" << endl;
    }
private:
    int b;
};

class Derive :public Base
{
public:
    Derive(int data = 0)
        :d(data)
    {
        cout << "Derive()" << endl;
    }
    ~Derive()
    {
        cout << "~Derive()" << endl; 
    }
private:
    int d;
};

int main()
{
    Derive d;
    d.fun();
    return 0;
}

编译后出错:

Error   1   error C2039: 'fun' : is not a member of 'Derive'    e:\demo\project1\project1\source.cpp    40  1   Project1
    2   IntelliSense: class "Derive" has no member "fun"    e:\DEMO\Project1\Source.cpp 40  4   Project1

编译器报错fun()函数不是派生类Derive的成员函数,即友元函数并没有被继承。

2.静态成员及静态成员函数能不能被继承

  了解这个问题之前,我们先确定一件事情,那就是,在基类和派生类中,静态成员和静态成员函数共用同一段空间。
  我们在以前的学习过程中都知道,类的模型是所有对象的数据成员单独存储,但是所有成员函数和静态成员是共用一段空间的
例如:

class Test
{
    public:
    int a;
    int b;
    int c;
    void fun()
    {}
    static int s;
};
int main()
{
    Test A,B,C;
    return 0;
}

上面的代码对应下图:
这里写图片描述
即,ABC各自有各自的数据段,但是成员函数和静态成员的内存是公有的。
我在这里通过下面的代码进行了认证:

#include <iostream>
using namespace std;
class Base
{
    friend void fun();
public:
    Base(int data = 0)
        :b(data)
    {
        cout << "Base()" << endl;
    }
    ~Base()
    {
        cout << "~Base()" << endl;
    }
    static void show()
    {
        cout << "static show()" << endl;
    }
    void add()
    {
        a++;
    }
    static int a;
private:
    int b;
};
int Base::a = 0;
class Derive :public Base
{
public:
    Derive(int data = 0)
        :d(data)
    {
        cout << "Derive()" << endl;
    }
    ~Derive()
    {
        cout << "~Derive()" << endl; 
    }
    void Add()
    {
        a++;
    }
private:
    int d;
};

int main()
{
    Derive d;
    d.show();
    d.a = 2;
    d.add();
    d.Add();
    cout << d.a << endl;
    return 0;
}   

运行结果如下:
这里写图片描述

现在准确得到了,基类与派生类的静态成员函数与静态成员是共用一段空间的,即静态成员和静态成员函数是可以继承的。

所以,我们可以得出以下结论:

  • 父类的static变量和函数在派生类中依然可用,但是受访问性控制(比如,父类的private域中的就不可访问)。而且对static变量来说,派生类和父类中的static变量是共用空间的,这点在利用static变量进行引用计数的时候要特别注意。
  • 派生类的friend函数可以访问派生类本身的一切变量,包括从父类继承下来的protected域中的变量。但是对父类来说,他并不是friend的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++继承详解之一——继承的三种方式、派生类的对象模型 的相关文章

  • Ardupilot EKF3核心算法《气压计,GPS更新融合》

    目录 文章目录 目录 摘要 1 高度融合源的选择 2 GPS的速度和位置测量序列的融合 2 1 得到GPS的观测方程 2 2 得到GPS的观测方程中的H矩阵 2 3 计算卡尔曼增益 2 2 得到GPS的测量数据 2 3 得到GPS的观测噪声
  • ardupilot 姿态误差计算分析

    目录 文章目录 目录 摘要 1 源码对比分析 1 之前代码 2 最新代码 2 结果对比 3 参考 4 结论 摘要 本节主要记录ardupilot 之前代码和最新代码姿态误差计算的核心代码分析 欢迎批评指正 1 源码对比分析 1 之前代码 2
  • Ubantu18.04 下编译PX4 环境配置

    1 用户权限准备 参考这篇博客进行 xff1a Pixhawk Ubuntu下编译原生固件PX4 外来务工人员徐某的博客 CSDN博客 2 源码的下载和子模块的更新 关于源码的下载 xff0c 由于诸多子模块的下载地址依然是github c
  • ardupilot 最优化算法

    目录 文章目录 目录 摘要 1 最小二乘法 1 1定义 1 2 基本思想 1 3 基本原理 1 4举例子 1 5最小二乘法和梯度法区别 2 梯度下降法 2 1 什么是梯度 2 2 什么是梯度下降 3 牛顿迭代法 3 0 牛顿迭代 3 1 牛
  • ardupilot 位置控制(POSHOLD)分析

    目录 文章目录 目录 摘要 0 简介 1 POSHOLD初始化过程 1 刹车增益的计算 2 位置保持不同阶段状态机对应的类型 2 POSHOLD运行过程 2 1 获取需要的飞行输入信息 2 2POSHOLD模式状态机 2 3获取当前的横滚俯
  • Ardupilot 飞控代码解锁流程分析

    摘要 本文档只有记录分析ardupilot飞控代码解锁的过程 如果有分析不到的地方 欢迎批评指导 谢谢 联系方式 18129927205 重点标志变量 flags armed 0表示没有解锁 flags armed 1表示解锁 arming
  • Ardupilot飞控Mavlink代码学习

    目录 文章目录 目录 摘要 1 Ardupilot怎么实现Mavlink初始化 2 Mavlink消息通信过程 摘要 本节主要记录自己学习Ardupilot的Mavlink协议的过程 欢迎一起交流分析 1 Ardupilot怎么实现Mavl
  • Ardupilot飞控姿态角与姿态角速度控制过程分析(超长篇)

    目录 文章目录 目录 摘要 1 自稳模式初始化 2 自稳模式更新函数 这个代码主要把横滚输入 俯仰输入量转换成目标角度需要的范围 也就是 4500 4500 3 姿态角速度代码控制过程分析 4 电机PWM控制运算 摘要 本节主要记录自己学习
  • PX4与Ardupilot的入门基础知识(第一章:架构与启动过程)

    目录 目录 摘要 第一节 px4与apm的区别与联系 第二节 px4与apm每个文件夹的作用 第三节 px4与apm无人机的启动过程 摘要 本节主要记录自己学px4的代码架构与Ardupilot代码架构对比文档 欢迎批评指正 1 px4与a
  • Ardupilot Pre-Arm安全检查程序分析

    目录 目录 摘要 第一 Pre Arm简介 第二 Pre Arm报错需知 1 使用前准备 使用Pre Arm信息分析不能解锁原因 2 解锁失败的原因 3 解锁失败的原因 自己对照官网进行翻译 1解锁前安全检查 2采用GCS识别是什么导致的P
  • STM32单片机汇编资料学习(1)

    目录 文章目录 目录摘要1 Cortex M3内核架构 在这里插入图片描述 https img blog csdn net 20181009223510343 watermark 2 text aHR0cHM6Ly9ibG9nLmNzZG4
  • Ardupilot 软件在环SITL仿真学习

    目录 文章目录 目录 摘要 1 配置SITL功能 2 SITL指令学习 1 如何起飞 2 如何上锁 3 如何降落 4 如何修改模式 5 如何修改遥控器输入 6 如何修改参数 摘要 本文主要学习Ardupilot 的软件在环SITL仿真功能
  • Ardupilot 串口代码学习

    目录 文章目录 目录 摘要 1 串口初始化 1 usb串口初始化 2 其他串口初始化 1 如何设置波特率和协议 2 GPS串口初始化 3 GPS数据更新 1 update instance 摘要 本节主要学习Ardupilot的串口资源代码
  • document三个方法获取对象

    主要方法 getElementById方法 span class token operator lt span span class token operator span DOCTYPE html span class token ope
  • 怎么判断c调用是内核调用还是库函数调用?

    man有如下的描述 The Linux man pages project documents the Linux kernel and C library interfaces that are employed by user prog
  • JDBC参数设置

    常用 JDBC 驱动名字和 URL 列表 ODBC driver sun jdbc odbc JdbcOdbcDriver jdbc odbc name 用 COM ibm db2 jdbc net DB2Driver 连接到 DB2 数据
  • Windows dos命令使用总结(持续更新)

    1 windows如何通过CMD命令结束某个端口的进程 xff1a netstat ano findstr 端口号tasklist findstr 进程PIDtaskkill PID 进程PID F windows常用命令 可可西 博客园
  • postgresql查询表元数据信息语句

    select tablename from pg tables where schemaname 61 39 public 39 and tablename like 39 table 39 order by tablename SELEC
  • SpringBoot 异常后更改响应状态码

    一 64 RestControllerAdvice和 64 ExceptionHandler拦截异常 package com lxk socket collector common import com lxk base bean Comm
  • linux进程kill命令关不掉

    1 Linux kill 命令用于删除执行中的程序或job 语法 xff1a kill s sigspec n signum sigspec pid jobspec or kill l sigspec kill s lt 信息名称或编号 g

随机推荐

  • linux tcpdump抓包命令使用详解

    一 抓包命令概述 作用 xff1a xff08 1 xff09 捕获网络协议包 xff08 2 xff09 分析网络协议包 分类 xff1a xff08 1 xff09 linux命令行工具 xff0c 如tcpdump xff08 2 x
  • wireshark抓包教程详解

    Wireshark软件安装 软件下载路径 xff1a wireshark官网 按照系统版本选择下载 xff0c 下载完成后 xff0c 按照软件提示一路Next安装 说明 xff1a 如果你是Win10系统 xff0c 安装完成后 xff0
  • docker打包流程常用方式

    完整的docker打包流程 把外网服务器上的docker搬到内网使用时 xff0c 报了两个错误 xff0c 外网容器到tar包都没问题 xff0c 在内网使用tar包的时候报了两个错误 cannot connect to the Dock
  • 5GC 网元AMF、SMF、UPF、PCF、UDM等介绍

    5GC 网元AMF SMF AUSF UPF PCF UDM NRF NSSF NEF介绍 1 AMF Access and Mobility Management Function xff0c 接入和移动性管理功能 xff0c 执行注册
  • 如何准备校招?

    秋招已经落尽尾声 xff0c 今天小牛想把自己的学习经验分享给大家 xff0c 避免大家多走弯路 1 首先需要确定自己想从事哪方面的工作 比如服务端开发 xff08 Java开发工程师 xff0c C 43 43 开发工程师 xff09 x
  • 5GC architecture N1、N2、N3、N4、N6等接口

    5GC architecture N1 N2 N3 N4 N6 N9 N26接口 N1接口 N1接口为UE和AMF间的信令面接口 N1是逻辑概念的接口 xff0c 不存在物理口 N1接口基于N2接口信令实现 N2接口 N2接口为 R AN和
  • FAQ:报红--maven本地有jar包仍从从远端下载

    问题 xff1a 最近编译项目 xff0c 发现有个模块依赖总是编译不过 xff0c 报无法download jar包 但是查看maven配置的远端仓库 xff0c 发现maven已不支持该jar包 但是本地确实存在 xff0c idea
  • SNMP(简单网络管理协议)详解

    一 简介 SNMP 简单网络管理协议 xff1a 专门用于在 IP 网络管理网络节点 xff08 服务器 工作站 路由器 交换机及HUBS等 xff09 的一种标准协议 xff0c 它是一种应用层协议 SNMP 使网络管理员能够管理网络效能
  • XXL-JOB分布式任务调度平台

    XXL JOB 是一个轻量级分布式任务调度平台 xff0c 其核心设计目标是开发迅速 学习简单 轻量级 易扩展 现已开放源代码并接入多家公司线上产品线 xff0c 开箱即用 Gitee 地址下载 xff1a https gitee com
  • 2万字详解,吃透 ES

    之前已经分享过Elasticsearch的使用和原理的知识 xff0c 由于近期在公司内部做了一次分享 xff0c 所以本篇主要是基于之前的博文的一个总结 xff0c 希望通过这篇文章能让读者大致了解Elasticsearch是做什么的以及
  • 手动回收Linux内存

    linux的内存分配是采用大页面的方式 xff0c 有可能会出现内存回收不及时导致系统卡住的情况 xff0c 这时候可以手工回收一下内存 执行 xff1a echo 1 gt proc sys vm drop caches 查看系统资源使用
  • spring-expression表达式详解

    一 概述 Spring Expression Language xff08 简称 SpEL xff09 是一个支持查询和操作运行时对象的强大的表达式 语言 贯穿着整个 Spring 产品组的语言 SpEL是单独模块 xff0c 只依赖于co
  • Docker容器整合wagon-ssh自动化部署SpringBoot工程

    一 前提条件 xff1a 机器上已经安装了docker 安装过程 准备部署的springboot的jar包Dockerfile文件部署脚本deploy sh升级脚本upgrade sh 二 准备Dockerfile 文件 创建一个Docke
  • TIME_WAIT和CLOSE_WAIT状态区别

    在服务器的日常维护过程中 xff0c 会经常用到下面的命令 xff1a netstat n awk 39 tcp 43 43 S NF END for a in S print a S a 39 它会显示例如下面的信息 xff1a TIME
  • 迭代过程:batch和epochs

    目录 引入 使用mini batch的优点 xff1a xff08 对比传统的梯度下降 更容易找到全局最优解 缺点 xff1a 要定义的两个超参数 xff1a batch size epochs 引入数据 TensorDataset Dat
  • PlantUML 语法之时序图

    文章目录 前言 96 gt gt 96 信息传递声明参与者的几个关键字 96 as 96 重命名参与者 96 96 添加颜色 96 order 96 定义参与者顺序 96 96 参与者名字给自己发信息修改传达信息的箭头样式修改箭头颜色 96
  • 基于ArUco的视觉定位(一)

    一 ArUco简介及安装步骤 ArUco a minimal library for Augmented Reality applications based on OpenCV xff0c 是科尔多瓦大学 人工视觉应用 研究小组 xff0
  • 基于ArUco的视觉定位(三)

    一 ArUco之Marker Mapper 1 Marker Mapper简介 Mapping and Localization from Planar Markers是A V A小组基于ArUco开发的一个利用二维码建图与定位的项目 论文
  • 关于《基于ArUco的视觉定位》系列博文撤回的通知

    由于近期我们要申请发明专利 xff0c 博客中涉及较多私密内容 xff0c 所以暂时不能公开了 我把之前的网页保存了图片格式 xff0c 有想继续学习的同学可以在本博客下方评论区留下你们的邮箱 xff0c 我会把相关内容私发给你们 收到邮件
  • c++继承详解之一——继承的三种方式、派生类的对象模型

    C 43 43 是OOP xff08 Object Oriented Programming xff09 语言 xff0c 即面向对象编程语言 OOP的核心思想就是数据抽象 xff08 类的设计 xff09 xff0c 继承和动态绑定 类展