当前位置: 首页 > news >正文

C++ Primer Plus第十三章笔记

目录

基类

构造函数:访问权限的考虑

1.2 派生类和基类之间的特殊关系

继承:is-a关系

多态公有继承

静态联编和动态联编

指针和引用类型的兼容性

虚成员函数和动态联编

虚函数的注意事项

构造函数

析构函数

友元

没有重新定义

重新定义将隐藏方法

访问控制:protected

抽象基类

继承和动态内存分配

情况1:派生类不使用new

情况2:派生类使用new

类设计回顾

编译器生成的函数

定义类(设计类)需要注意的问题

公有继承的考虑因素

C++类提供了类库来提高重用性。类库由类声明和实现构成,以源代码的方式提供,所以要修改满足不同的需求,就需要修改代码。

C++提供类继承来扩展和修改类。类继承从已有的类派生出新的类,而派生类继承原有类(基类)的特征,包括方法。

继承可以完成的工作

  • 在已有类的基础上添加功能
  • 可给类添加数据
  • 可修改类方法的行为

基类

从一个类派生出另一个类时,原始类称为基类继承类称为派生类

继承的声明格式(公有继承):

//public表面声明是一个公有基类,公有派生类
class leaves : public root
{......
}// 书中例子
class RatePlayer : public TableTennisPlayer //基类(原始类):TableTennisPlayer,派生类(继承类):RatePlayer
{......
}

派生类对象(上述code中的RatePlayer)的特征:

  • 派生类对象存储了基类的数据成员(派生类继承了基类的实现
  • 派生类对象可以使用基类的方法(派生类继承了基类的接口

构造函数:访问权限的考虑

⚠️注意:派生类不能直接访问基类的私有成员,而必须通过基类公有方法来进行访问私有的基类成员。具体来说,派生类构造函数必须使用基类构造函数。

派生类构造函数的要点

  • 创建派生类首先创建基类对象
  • 派生类构造函数应通过成员初始化列表将基类信息传递给基类构造函数
  • 派生类构造函数应初始化派生类新增的数据成员。
RatedPlayer::RatedPlayer(unsigned int r,const string &fn,const string &ln,bool ht):TableTennisPlayer(fn,ln,ht) // :TableTennisPlayer(fn,ln,ht) 是成员初始化列表
{rating=r;
}

派生类对象的释放顺序与创建对象时的顺序相反(首先执行派生类的析构函数目,然后自动调用基类的析构函数)。

1.2 派生类和基类之间的特殊关系

  • 派生类对象可以使用基类的方法,条件是方法不是私有的。
  • 基类指针可以在不进行显式类型转换的情况下指向派生类对象
  • 基类引用可以在不进行显式类型转换的情况下引用派生类对象
// 基类:TableTennisPlayer,派生类:RatedPlayer
RatedPlayer rplayer(1140, "Mallory", "Duck", true);
rplayer.Name(); //通过基类方法来继承
TableTennisPlayer & rt = rplayer;
TableTennisPlayer * pt = &rplayer;
rt.Name(); // 使用引用方式来引用派生类对象
pt->Name(); //指针方式来指向派生类对象

基类指针引用只能用于调用基类方法。因此,不能使用 rt 或 pt来调用派生类的 ResetRanking 方法。

C++中要求引用和指针类型与赋给的类型匹配,但这规则对于继承来说是一种单向例外,不可以将基类对象和地址赋给派生类引用和指针。

如果基类引用和指针可以指向派生类对象,则如下情况均可正常使用:

  • 基类引用定义的函数或指针参数可用于基类对象或派生类对象。
    • 形参为基类引用时,可指向基类对象或派生类对象。
    • 形参为指向基类的指针的函数,可使用基类对象的地址或派生类对象的地址作为实参。
  • 引用的兼容性问题允许将基类对象初始化为派生类对象。
  • 可将派生类对象赋给基类对象。

继承:is-a关系

C++中3种继承方式:

  • 公有继承
  • 保护继承
  • 私有继承

公有继承是最常用的方式,建立一种 is-a 关系。即派生类对象也是一个基类对象,可对基类对象执行的任何操作,也可对派生类对象执行。

多态公有继承

多态:同一个方法的行为随上下文而异。

实现多态公有继承的两种机制:

  • 在派生类中重新定义基类的方法
  • 使用虚方法

使用 virtual 方法,程序会根据引用或指针指向的对象的类型来选择方法,而不是根据引用或指针类型来选择方法。

如果要在派生类会重新定义基类的方法,通常将基类方法声明为虚的。即在类方法声明前加上 virtual 关键字。被virtual声明的类方法称为虚方法

class BrassPlus:public Brass
{private:......public:......virtual void ViewAcct() const; //虚方法virtual void Withdraw(double amt); // 虚方法
}

静态联编和动态联编

函数名联编:将源代码中的函数调用解释为执行特定的函数代码块。

静态联编(早期联编):在编译过程中进行联编。

动态联编(晚期联编):编译器生成能够在程序运行时选择正确的虚方法的代码。

指针和引用类型的兼容性

  • 向上👆强制转换:将派生类引用或指针 ---------> 基类引用或指针。⚠️公有继承不需要进行显式类型转换。

    向上强制转换是可传递的。

  • 向下👇强制转换:将基类指针或引用 ---------> 派生类引用或指针。如果不使用显式类型转换,则向下强制转换不允许使用。

  • 隐式向上强制转换使基类指针或引用可以指向基类对象或派生类对象,因此需要动态联编。C++虚成员函数来能满足这种需求。

虚成员函数和动态联编

编译器对非虚方法使用静态联编,而对于虚方法使用动态联编。

  • 有两种类型联编的原因?

    • 效率

      动态联编为使程序可在程序运行阶段进行决策,则必须采取一些方法来跟踪基类指针或引用指向的对象类型,但会增加额外的处理开销。此时静态联编效率更高。

      C++的指导原则之一:不要为不适用的特性付出代价。仅当程序设计确实需要虚函数时,才使用它们。

    • 概念模型

  • 虚函数的工作原理 C++规定了虚函数的行为,实现方法还是需要由编译器作者负责。

编译器处理虚函数的方法:给每个对象添加一个隐藏成员。隐藏成员中保存了一个指向函数地址数组的指针。这种数组称为虚函数表(Virtual function table,vtbl)。虚函数表中存储了为类对象进行声明的虚函数的地址。

使用虚函数时,在内存和执行速度方面存在的成本:

  • 每个对象都将增大,增大量为存储地址的空间;

  • 对于每个类,编译器都创建一个虚函数地址表(数组);

  • 对于每个函数调用,都需要执行一项额外的操作,即到表中查找地址。

虚函数的注意事项

  • 在基类方法的声明中使用关键字 virtual,可使该方法在基类以及所有派生类(包括派生类的方法)都是虚的。

  • 如果使用指向对象的引用或指针调用虚方法,程序将使用对象类型定义的方法,而不使用为引用或指针类型定义的方法。这称为动态联编晚期联编

  • 如果定义的类将被用作基类,则应将要在派生类中重新定义的类方法声明未为虚的。

构造函数

构造函数不能是虚函数。派生类不继承基类的构造函数,所以将构造函数声明为虚的无意义。

析构函数

析构函数应声明为虚函数,除非类不用做基类。

即使基类不需要显式析构函数提供服务,也不应依赖于默认构造函数,而 应提供虚构函数,即使它不执行任何操作

友元

友元不能是虚函数,因为设计的问题,友元不是类成员,而是通过让友元函数使用虚成员函数来解决。

没有重新定义

如果派生类没有重新定义函数,将使用函数的基类版本。如果派生类位于派生链中,则将使用最新的虚函数版本

重新定义将隐藏方法

重新定义不会生成函数的两个重载版本,而是隐藏了基类版本。

  • 如果重新定义继承的方法,应确保与原来的原型完全相同,但如果返回类型是基类引用或指针,则可以修改为指向派生类的引用或指针,这种特性称为 返回类型协变(Covariance of return type)

    允许返回类型随类型的变化而变化。⚠️注意:只适用于返回值,不适用于参数

  • 如果基类声明被重载,则应在派生类中重新定义所有的基类版本。

访问控制:protected

控制对类成员访问权限的三个关键字:private、public、protected

关键字 protected 和 private类似,在类外只能使用公有类成员来访问 protected 部分中的类成员

private和protected的区别:派生类成员直接访问基类的保护成员,但不能直接访问基类的私有成员。

对外部而言,保护成员的行为与私有成员类似,对派生类来说,保护成员的行为与公有成员类似。

// Brass类将balance成员声明为保护的
class Brass
{protected:double balance;...
};

⚠️警告:最好对数据成员采用私有访问控制,不要使用保护访问控制,同时通过类方法使得派生类能够访问基类数据。

对成员函数来说,保护控制可以让派生类能够访问公众无法使用的内部数据。

抽象基类

在类声明中包含纯虚函数时,则该类就是**抽象基类(Abstract Base Class,ABC)**。

C++通过使用纯虚函数(pure virtual function)提供未实现的函数。纯虚函数声明的结尾处为=0

class BaseEllipse //抽象基类
{private:...public:...virtual double Area() const = 0; //纯虚函数
};

如果在类声明中包含纯虚函数时,则不能创建该类的对象。

ABC描述的是至少使用一个纯虚函数的接口,从ABC派生出的类将根据派生类的具体特征,使用常规虚函数来实现接口。 [] ABC要求具体派生类覆盖其纯虚函数 -

继承和动态内存分配

如果派生类也使用动态内存分配(使用new和delete进行),有如下几个技巧:

情况1:派生类不使用new

假设基类使用动态内存分配:

// Base Class Using DMA(Dynamic Memory Allocation)
class BaseDMA
{private:char *label;int rating;public:baseDMA(const char * l = "null", int r = 0);baseDMA(const baseDMA & rs); // 复制构造函数(处理内存分配)virtual ~baseDMA(); //虚析构函数baseDMA & operator=(const baseDMA & rs); //赋值运算符重载......
};

如果在基类中已经使用了动态内存分配(已定义显式析构函数、复制构造函数和赋值运算符),则在派生类中无需使用动态内存分配。

// derived class without DMA
class lackDMA:public baseDMA
{private:char color[40];public:......
};

此时的派生类lackDMA类不需要定义显式析构函数、复制构造函数和赋值运算符。

情况2:派生类使用new

如果基类和派生类也使用了动态内存分配:

class hasDMA: public baseDMA
{private:char * style; // 构造函数中使用newpublic:......
};

此时需要为派生类定义显式析构函数、复制构造函数和赋值运算符。对应的定义方法如下:

  • 析构函数

    派生类析构函数自动调用基类的析构函数,故其自身职责:对派生类构造函数执行工作的清理。

    baseDMA::~baseDMA()
    {delete [] label;
    }
    hasDMA::~hasDMA()
    {delete [] style;
    }

  • 复制构造函数

    复制构造函数只能访问自身的数据,不能访问基类的私有数据,所以必须调用基类的复制构造函数来进行数据共享。

    // 成员初始化列表将hasDMA引用传递给baseDMA构造函数。
    hasDMA::hasDMA(const hasDMA & hs):baseDMA(hs) //基类引用可以指向派生类型。
    {style = new char[std::strlen(hs.style) + 1];std::strcpy(style,hs.style);
    }

    所以,baseDMA复制构造函数将使用hasDMA参数的baseDMA部分来构造新对象的baseDMA部分。

  • 赋值运算符

    派生类的显式赋值运算符必须负责将所有继承的baseDMA基类对象的赋值,可通过显式调用基类赋值运算符来进行该操作。

    hasDMA & hasDMA::operator=(const hasDMA & hs) //hasDMA使用DMA,所以需要一个显式复制运算符
    {if(this == &hs)return *this;baseDMA::operator=(hs); // 与 *this = hs 相同delete [] style;style = new char[std::strlen(hs.style) + 1];std::strcpy(style, hs.style);return *this;
    }

总结

当基类和派生类都采用动态内存分配时,派生类的析构函数、复制构造函数、赋值运算符都必须使用相应的类方法来处理基类元素。三种方式来满足:

  • 析构函数:自动完成
  • 构造函数:通过在初始化成员列表中调用基类的复制构造函数来完成。否则会自动调用基类的默认构造函数。
  • 赋值运算符:通过 作用域解析运算符 来显式调用基类的赋值运算符来完成。

类设计回顾

C++可用于解决各种类型的编程问题,但不能将类设计简化成带编号的例程。

编译器生成的函数

编译器会自动生成一些公有成员函数 -----> 特殊成员函数。

  • 默认构造函数

    • 默认构造函数要么没有参数,要么所有的参数都有默认值。

    • 如果没有定义任何构造函数,编译器将定义默认构造函数,便于创建对象。

    • 如果在派生类构造函数中成员初始化列表中没有显式调用基类构造函数,则编译器将使用基类的默认构造函数来构造派生类对象的基类部分。

      如果基类此时没有构造函数,将导致编译错误。

    • 构造函数的作用:确保对象总能被正确的初始化。

  • 复制构造函数

    复制构造函数接受其所属类的对象作为参数。使用复制构造函数的情况:

    • 将新对象初始化为一个同类对象。
    • 按值将对象传递给函数。
    • 函数将值返回对象。
    • 编译器生成临时对象。

    如果程序没有使用,则编译器提供原型,但不提供函数定义。

  • 赋值运算符

    • 默认的赋值运算符用于处理同类对象之间的赋值。

      初始化:语句创建新的对象;赋值:语句修改已有对象的值。

    • 编译器不会生成将一种类型赋给另一种类型的赋值运算符,所以要么显式定义,要么使用强制类型转换。前者容易导致编译器出现混乱,所以一般使用后者。
  • 默认析构函数

定义类(设计类)需要注意的问题

  • 构造函数

    用于创建新的对象,其他类方法只是被现有的对象调用,所以不能被继承。

  • 析构函数

    如果使用new进行动态内存分配,则一定要定义显式析构函数来完成类对象执行后的清理。基类应提供一个虚析构函数(即使不执行任何操作)。

  • 转换 C++11支持用explicit。使用explicit允许进行显式转换,禁止隐式转换。

  • 按值传递对象与传递引用

    编写使用对象作为参数的函数时,应按引用传递对象(不使用按值传递)。原因如下:

    • 提高效率
    • 在继承使用虚函数时,被定义为接受基类引用参数的函数可以接受派生类。

    如果不修改引用,则将参数声明未const引用。

  • 返回对象和返回引用

    • 唯一区别:函数原型和函数头。
    • 应返回引用而不是返回对象的原因:返回引用可节省时间和内存。
    • ⚠️注意:函数不能返回临时对象的引用 -----> 函数结束,临时对象消失,所以引用不合法。
  • 使用const

    • 修饰参数 -----> 确保方法不修改参数。
    • 修饰方法 -----> 确保方法不修改调用它的对象。
    • 修饰返回引用的函数 -----> 确保引用或指针返回的值不能用于修改对象中的数据。

公有继承的考虑因素

  • is-a关系

    遵循 is-a 关系,如果派生类不是特殊的基类,则不要使用公有派生。

  • 什么不能被继承?

    • 构造函数
    • 析构函数
    • 赋值运算符
  • 私有成员与保护成员

    • 将基类成员设置私有可提高安全性,设置保护可简化代码编写,提高访问速度。
    • 但一般将基类的数据成员设为私有成员,而将方法设置为保护成员。
  • 虚方法

    在设计基类时,必须确定是否将类方法声明为虚的。

    • 如果派生类需要重新定义方法,则在基类中将方法设置为虚的。
    • 如果不需要,则不必将其声明为虚的。
  • 析构函数

    • 基类的析构函数应是虚的(virtual)。
  • 友友函数

    友元函数不是类成员,所以不能被继承。

    • 如果希望派生类的友元能使用基类的友元,可通过强制类型转换符。

      将派生类引用或指针转换为基类引用或指针,然后使用转换后的来调用基类的友元。

相关文章:

C++ Primer Plus第十三章笔记

目录 基类 构造函数:访问权限的考虑 1.2 派生类和基类之间的特殊关系 继承:is-a关系 多态公有继承 静态联编和动态联编 指针和引用类型的兼容性 虚成员函数和动态联编 虚函数的注意事项 构造函数 析构函数 友元 没有重新定义 重新定义将隐…...

【JavaEE】单例模式

作者主页:paper jie_博客 本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。 本文于《JavaEE》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造&…...

第十五届蓝桥杯模拟赛(第二期 C++)

俺自己做的噢,还未核实答案,若有差错,望斧正。 第一题 小蓝要在屏幕上放置一行文字,每个字的宽度相同。小蓝发现,如果每个字的宽为 36 像素,一行正好放下 30 个字,字符之间和前后都没有任何空隙…...

关于Unity中字典在Inspector的显示

字典在Inspector的显示 方法一:实现ISerializationCallbackReceiver接口 《unity3D游戏开发第二版》记录 在编辑面板中可以利用序列化监听接口特性对字典进行序列化。 主要继承ISerializationCallbackReceiver接口 实现OnAfterDeserialize() OnBeforeSerialize() …...

使用Plex结合cpolar搭建本地私人媒体站并实现远程访问

文章目录 1.前言2. Plex网站搭建2.1 Plex下载和安装2.2 Plex网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 用手机或者平板电脑看视频,已经算是生活中稀松平常的场景了,特别是各…...

svn合并冲突时每个选项的含义

合并冲突时每个选项的含义 - 这个图片是 TortoiseSVN(一个Subversion(SVN)客户端)的合并冲突解决对话框。当你尝试合并两个版本的文件并且出现差异时,你需要解决这些差异。这个对话框提供了几个选项来处理合并冲突&…...

指针、数组与函数例题3

1、字符串复制 题目描述 设计函数实现字符串复制功能,每个字符串长度不超过100,不要使用系统提供的strcpy函数 输入要求 从键盘读入一个字符串到数组b中,以换行符结束 输出要求 将内容复制到另一个数组a中,并分别输出数组a和…...

ThreeJs样例 webgl_shadow_contact 分析

webgl_shadow_contact 官方样例中,对阴影的渲染比较特殊,很值得借鉴,学习渲染阴影的思路;这个例子中对阴影的渲染,并没有使用任何光源,没有用shadowmap的常规方式 渲染阴影;而是使用了深度材质T…...

Nginx(缓冲区)

先来思考一个问题,接入Nginx的项目一般请求流程为:“客户端→Nginx→服务端”,在这个过程中存在两个连接:“客户端→Nginx、Nginx→服务端”,那么两个不同的连接速度不一致,就会影响用户的体验(…...

MQTT协议理解并实践

MQTT是一个轻量的发布订阅模式消息传输协议,专门针对低带宽和不稳定网络环境的物联网应用设计 MQTT协议根据主题来分发消息进行通信,支持通配符匹配,可以低开销的使用数百万Topic进行一对一,一对多双向通信。 协议特点 1. 开放…...

实现一个简单的网络通信下(udp)

时间过去好久了,先回忆一下上一篇博客的代码!! 目前来看,我们客户端发一条消息,我服务器收到这一条消息之后呢,服务器也知道了是谁给我发来的消息,紧接这就把这条消息放进buffer当中&#xff0c…...

Linux中office环境LibreOffice_7.6.2下载

阿里云盘:LibreOffice_7.6.2 使用:下载的文件为exe文件,双击exe文件即可获取到文件 LibreOffice_7.6.2安装: 解压:tar -zxvf LibreOffice_7.6.2_Linux_x86-64_rpm.tar.gz 移动到RPMS目录:cd LibreOffice_7…...

Linux快捷控制

Linux快捷控制 工具安装 yum -y install lrzsz wget curl net-tools git防火墙 systemctl status firewalld.service systemctl stop firewalld.service systemctl disable firewalld.service宝塔 yum install -y wget && wget -O install.sh https://download.bt.…...

免费插件集-illustrator插件-Ai插件-重复复制-单一对象页面排版

文章目录 1.介绍2.安装3.通过窗口>扩展>知了插件>重复复制4.总结 1.介绍 本文介绍一款免费插件,加强illustrator使用人员工作效率,进行制卡专用分层分色。首先从下载网址下载这款插件 https://download.csdn.net/download/m0_67316550/8789050…...

GO基础之变量与常量

标识符与关键字 标识符 在编程语言中标识符就是程序员定义的具有特殊意义的词,比如变量名、常量名、函数名等等。 Go语言中标识符由字母数字和_(下划线)组成,并且只能以字母和_开头。 举几个例子:abc, _, _123, a123。 关键字 关键…...

Docker Compose简单入门

Docker Compose 简介 Docker Compose 是一个编排多容器发布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。 Docker Compose 真正的作用是在一个文件(docker-compose.yml)中定义并运…...

使用 PHPMailer 实现邮件的实时发送

💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 今天我们利用GitHub上20K星星的项目 PHPMailer…...

在Spring Boot中使用JavaMailSender发送邮件

用了这么久的Spring Boot,我们对Spring Boot的了解应该也逐步进入正轨了,这篇文章讲的案例也在我们的实际开发中算是比较实用的了,毕竟我们完成注册功能和对用户群发消息,都可以采用到邮箱发送功能,往下看,…...

python动态圣诞下雪图

运行图片 代码 import pygame import random# 初始化Pygame pygame.init()# 创建窗口 width, height 800, 600 screen pygame.display.set_mode((width, height)) pygame.display.set_caption(Christmas Tree)# 定义颜色 GREEN (34, 139, 34) RED (255, 0, 0) WHITE (255…...

随心玩玩(十)git

写在前面:研究生一年多了,一直浑浑噩噩的,在深度学习的泥潭挣扎了好久,终于走出了精神内耗的泥潭…好久没有写博客了,决定重新捡起来…记录一下学习吧~ 之前写了一篇git的博客,【github 从0开始的基本操作…...

每日一练【盛最多水的容器】

一、题目描述 11. 盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&…...

Linux C语言 38-进程间通信IPC之信号

Linux C语言 38-进程间通信IPC之信号 本节关键字:C语言 进程间通信 信号量 semaphore 相关库函数:sem_init、sem_post、sem_wait、sem_destroy 提示:先做内容框架梳理,后期进行完善补充! 什么是信号量? …...

前端使用 xlsx.js 工具读取 excel 遇到时间日期少 43 秒的解决办法

在使用 xlsx 读取 excel 的时间格式的数据时,如 ‘2023-11-30’,‘2023/11/30’ ,默认会读取一串数字字符串,如:‘45260’,此时需要在 read 的时候传入一个配置项: import { read } from xlsxc…...

问题记录-maven依赖升级或替换(简单版)

问题背景 项目被检测到有高危漏洞,需要对部分jar进行升级。以一个jar为例记录一下升级过程。 1 找到高危漏洞的包 如果装了maven helper插件则可以在下面查看当前模块依赖包 2 使用maven命令 执行下面这个命令,会将当前项目的信息打印出来,…...

00Hadoop数据仓库平台

在这里是学习大数据的第一站 什么是数据仓库常见大数据平台组件及介绍 什么是数据仓库 在计算领域,数据仓库(DW 或 DWH)也称为企业数据仓库(EDW),是一种用于报告和数据分析的系统,被认为是商业智…...

java-jar包

jar包类似于压缩包,主要是组织和分享自己的Java代码方便,将一组特定的java文件打包,一般是.class文件,不过并不限制文件类型,都可以打包。 jar包中包好清单文件,如果没有指定就会自动生成默认的&#xff0…...

Flink运行时架构核心概念

Flink运行时架构 JobManager:协调,决定何时调度下一个task,对失败任务做恢复。 ResourceManager: 负责Flink集群中的资源提供、回收、分配,它负责管理task slot。standalone模式下,不能自行启动新的taskmanagerDispatc…...

docker安装达梦数据库并挂在数据卷

离线包下载地址:请点击 1.在线下载 wget https://download.dameng.com/eco/dm8/dm8_20230808_rev197096_x86_rh6_64_single.tar2. 导入镜像 docker load -i dm8_20230808_rev197096_x86_rh6_64_single.tar3. 运行容器 docker run -d -p 5236:5236 --restartalwa…...

ROS第一个程序——helloworld

目录 一、工作空间的创建 1.创建工作空间并初始化 2.进入 src 创建 ros 包并添加依赖 二、C实现helloworld C源码实现 编辑 ros 包下的 Cmakelist.txt文件 进入工作空间目录并编译 执行 三、python实现helloworld 进入 ros 包添加 scripts 目录并编辑 python 文件 …...

【Python 训练营】N_17 冒泡排序

题目 列表L [3,2,5,6,1,3,8,1,9],冒泡排序实现从小到大排列。 分析 冒泡排序的基本思想是从序列的第一个元素开始,依次比较相邻的两个元素,如果它们的顺序错误就交换它们的位置,直到整个序列有序为止。具体步骤如下&#xff1…...

河北网站建设seo优化/营销型企业网站的功能

项目一直从dotnet core 1.1开始,升级到2.0,乃至如今2.1,以后保持继续更新。 但可能只是一个后台,前台的话,到时候看有没有好的模板。 ------------无聊的分割线------------- 项目git仓库:https://github.c…...

wordpress主题图片修改/介绍网络营销的短文

本来今年提前60天抢票以为可以抢到自己心仪的票,高高兴兴的回家去的,可是天不从人意,各种抢票软件都使用了还是没有抢到票,最后还是通过Q群的黄牛买到了票。 虽然最近12306发生的信息泄露问题,我也上去修改了密码&…...

青岛模版网站建设/简述什么是seo及seo的作用

副标题——别把技术问题转化为人际问题(作者:孙继滨)【项目经理之修炼】 全文索引 刚刚进入项目时,由于权威还没有树立,人际关系尚浅,经常会有组员不把你当回事儿。于是: 你要求组员写周报&…...

个人网站毕业论文/黄页88网站推广方案

Mode Decision(模式选择)决定一个宏块以何种类型进行分割。宏块的分割类型有以下几种: 12345678910111213141516171819202122232425//P_Skip and B_Skip means that nothing need to be encoded for this macroblock ,// just use the mv predicted to restruct …...

如何用电脑做网站服务器吗/云南网站seo服务

点击上方 "zhisheng"关注, 星标或置顶一起成长Flink 从入门到精通 系列文章随着互联网飞速发展,企业业务种类会越来越多,业务数据量会越来越大,当发展到一定规模时,传统的数据存储结构逐渐无法满足企业需求,…...

把开发的网站让外网能访问要怎么做/seo短视频入口

从实际教学应用表明,多媒体教室教学设备计算机加投影机和电动幕配置方案已经应用多年,优点是投资相对小,缺点是投影机灯泡的耗材较昂贵,后续维护成本高,目前投影机灯泡的使用年限为2千小时,基本满足第一年的…...