51、C++ 学习笔记

news2025/2/10 22:16:43

1、引用类型

        引用类型是C++引入的新类型,根据汇编的知识进行理解,程序在汇编后,变量名将失去意义,因为汇编码将替换成用内存的(链接地址or运行地址)访问变量。在C/C++语言中,用变量名表示变量所占的那块内存,为了使多个名称绑定一个变量,C++引入了引用类型。其主要目的就是让变量名和变量能够真正的区分开,C语言中变量名和变量是1对1的,是分不开的。
        int i = 1;    //栈中分配sizeof大小内存,内存里的值为1,i <=> 内存的标号。
        int &ri = i; //给变量取一个别名ri,ri <=> i。
注意:定义引用,并不是定义变量,因为定义引用是不开辟空间的。可以理解为定义变量名,所以它必须初始化,必须与变量绑定起来。

2、const限定符

        const 对象必须初始化:
                const int j = 42;             //正确(编译时初始化)
                const int i = get_size(); //正确(运行时初始化)
                const int i;                     //错误
        const 与普通类型的组合:
                const int 与int const是等价的
                const float 与 float const是等价的
                。。。。   
        const 与指针类型组合(仅指针):
                int c1 = 0;
                const int c2 = 0;
                const int *p1 = &c1;  //左侧const限定右边的变量,即c1不能改变,限定右边的叫低层const
                int * const p2 = &c2; //右侧const限定左边的变量,即p2不能改变,限定左边的叫顶层const
                const int *const p3 = p2;  //左右边的值都被限定,都不能改变
        const 与引用的组合:
                const int &ri = c2;  //仅此一种写法,且只限定右边的变量
        注意:const限定的都是变量,无论左边还是右边的变量都是左值,它并不针对右值。
        注意:左值和右值不是根据在 = 号左的右来区分的(百度上有很多根据等于号这样的错误说法)

3、命名空间的写法

写法一:在cpp文件中,每个变量的定义都加上命名空间的名称。

 写法二:在cpp文件中,每个变量的定义都用namespace框起来。

4、泛型编程的基础=>模板

0、面向对象编程和泛型编程都是一种编程范式。
1、C++ Primer(第五版):面向对象编程(OPP)和泛型编程都能处理在编写程序时不知道类型的情况。不同之处在于:
        OPP能处理类型在程序运行之前都未知的情况。(运行时知类型)
        泛型编程中,编译时就能获得其类型了。(编译时知类型)
2、模板和宏定义很像,但是二者不同,例如:宏定义有直接替换而不检查的缺陷,而模板没有此缺陷。具体可以参考匿名类或结构体的使用。(类似但不同,模板更安全=>非替换=>根据参数反推实例化类型)
3、编译过程无法区分类是不是被实例化过:所以会被编译进可执行文件中。
      编译过程可以区分类模板是不是被实例化过:所以会选择性的编译进可执行文件中。(类模板的转换发生在编译期间,如何编译期间未被实例化过,就不会被编译进可执行文件中)
4、                                          类定义==实例化==>对象    (类的实例化发生在运行期间)
        类模板定义==实例化==>类定义==实例化==>对象    (类模板的实例化发生在编译期间)

5、C++标准库(STL)之顺序型容器
        vector:可变大小数组
        deque:双端队列
        list:双向链表
        forward_list:单向链表
        array:固定大小数组
        string:与vector相似,但专门用于保存字符
        =====>顺序容器适配器
        stack:栈适配器,默认情况下基于dequeue实现
        queue:队列适配器,默认情况下基于dequeue实现
        priority_queue:优先队列适配器,默认情况下基于vector实现
6、C++标准库(STL)之关联性容器
        =====>按关键字有序保存
        map:关联数组
        set:关键字即值,只保存关键字的容器
        multimap:关键字可重复出现的map
        multiset:关键字可重复出现的set
        =====>关键字无序保存
        unordered_map:用哈希函数组织的map
        unordered_set:用哈希函数组织的set
        unordered_multimap:哈希组织的map;关键字可以重复出现
        unordered_multiset:哈希组织的set;关键字可以重复出现

总结:宏定义可以摆脱变量类型,但不具备类型的检查。模板不仅可以拜托变量类型,还可以进行类型的检查。泛型编程作用举例:函数重载时,函数逻辑相同,但形参类型不同,要写不同的函数,有了函数模板,只需要写一个函数就行了。

//vector使用示例========================================
int main()
{
    std::vector<int> vec = { 1, 2, 3 };
    vec.insert(vec.begin(), 11);
    vec.push_back(99);
    //vector<int>::iterator it = vec.begin();
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << std::endl;
    }
    std::cout << "<======>" << std::endl;
    for (auto& x : vec) {
        std::cout << x << std::endl;
    }
    return 0;
}

5、OOP的三大特征之类的封装

0、这里主要说明类的构造函数和初始化参数列表。
1、类的缺省构造函数

#include <iostream>
class Point{
public:
    int x;
    int y;
};
int main(int argc,char* argv[]){
    Point pt;  //调用缺省构造函数
    //Point pt();
    pt.x = 0;
    pt.y = 1;
    return 0;
}

==>说明:在不定义构造函数,会生成一个缺省构造函数,如下所示
class Point{
public:
    Point(){
       //一些默认初始化操作
    };
    int x;
    int y;
};

 2、一旦你定义构造函数,将不再生成缺省构造函数

#include <iostream>
class Point {
public:
    Point(int j, int k) {
        this->x = j;
        this->y = k;
    }
    int x;
    int y;
};
int main(int argc, char* argv[]) {
    //Point pt;     //错误,没有缺省构造函数
    Point pt(5, 5); //正确
    pt.x = 0;
    pt.y = 1;
    std::cout << pt.x << std::endl;
    std::cout << pt.y << std::endl;
    return 0;
}

=>说明:C++11允许我们使用=default来生成一个默认的构造函数
class Point {
public:
    Point() = default;
    Point(int j, int k) {
        this->x = j;
        this->y = k;
    }
    int x;
    int y;
};

  3、初始化参数列表

1、定义时初始化
class Point {
public:
    Point() = default;
    Point(int _x, int _y) : x(_x), y(_y) {
        
    }
    int x = 0;
    int y = 0;
};
2、定义后初始化
class Point {
public:
    Point() = default;
    Point(int _x, int _y){
        this->x = _x;
        this->y = _y;
    }
    int x = 0;
    int y = 0;
};
=>总结:初始化列表:
    对类的成员进行:定义时初始化
    初始化列表仅适用于构造函数(初始化列表是初始化成员变量的)

6、OOP的三大特征之类的继承

0、这里主要说明父类的构造函数和构造函数执行的顺序。
1、父类无缺省构造函数时,要显式调用父类的构造函数:

#include <iostream>
using namespace std;
class A {
public:
    A(int y) {
        std::cout << "A()" << std::endl;
    }
    ~A() {
        std::cout << "~A()" << std::endl;
    }
};

class Point: public A{
public:
    Point(int j, int k):A(3){  //显式调用父类的构造函数
        this->x = j;
        this->y = k;
        std::cout << "Point(int j, int k)" << std::endl;
    }
    int x;
    int y;
};
int main(int argc, char* argv[]) {
    Point pt(1, 2);
    return 0;
}

2、C++的初始化方式:直接初始化、拷贝初始化
      直接初始化:            =>调用构造函数的初始化
                int i(5);  //类中不可用
                int i{5};
                int i = int(5);
      拷贝初始化:            =>调用拷贝函数的初始化
                int i = 1;    //需要注意的是,这里发生了强制转换(直接初始化不存在强制转换问题)
需要注意的是:类是C++的相对于C的新增部分,其在类内成员变量初始化问题上,有一个规定,即类内部的()全被解释为函数调用,所以类内只能用=和{}进行初始化,而不能使用()。
3、基类的实例化顺序:
        1、实例化成员变量。
        2、执行类的构造函数。
4、子类的实例化顺序:先按继承顺序实例化每个父类,最后再实例化子类。(析构相反)

基类实例化 => 子类实例化 => 子类析构 => 基类析构

示例程序:

#include <iostream>
using namespace std;
class A {
public:
    A(int a) { cout << "A():id = "<< this << endl; }
    ~A() { cout << "~A():id = " << this << endl; }
};
class B {
public:
    B(int b) { cout << "B():id = " << this << endl; }
    ~B() { cout << "~B():id = " << this << endl; }
    A obj{ 2 };
};
class Point :public B, A {
public:
    Point(int x, int y):A(2),B(3) { cout << "Point():id = " << this << endl; }
    ~Point() { cout << "~Point():id = " << this << endl; }
};
int main(int argc, char* argv[]) {
    Point pt(5, 5);
    return 0;
}

打印如下:  先实例化B => 再实例化A => 最后实例化Point
        A():id = 005AFBE4          // B
        B():id = 005AFBE4          // B
        A():id = 005AFBE6          // A
        Point():id = 005AFBE4    //Point
        ~Point():id = 005AFBE4
        ~A():id = 005AFBE6
        ~B():id = 005AFBE4
        ~A():id = 005AFBE4

8、OOP的三大特征之类的多态

0、C++允许基类类型的指针指向子类的对象。
1、C++中,主要有两种类型的多态性:
        编译时多态性(静态多态性):
                函数重载、运算符重载、模板。
        运行时多态性(动态多态性):
                虚函数、多态继承。
2、主要是动态多态性:同一操作总用于不同的对象,可以有不同的执行结果
      实现方式:基类的虚函数、子类函数重写(覆盖)、基类指针
      关键字:基类中定义virtual函数、子类中重写并添加override,(override可以不加,但建议加上,因为加上override不仅可以进行规则检查,还可以增加代码的可读性)

#include <iostream>
class Shape {
public:
  virtual void draw() {
    std::cout << "Drawing shape...\n";
  }
};

class Rectangle : public Shape {
public:
  void draw() override {
    std::cout << "Drawing rectangle...\n";
  }
};

class Circle : public Shape {
public:
  void draw() override {
    std::cout << "Drawing circle...\n";
  }
};

int main() {
  Shape* shapes[2];
  shapes[0] = new Rectangle();
  shapes[1] = new Circle();

  for (int i = 0; i < 2; i++) {
    shapes[i]->draw();
  }

  return 0;
}

3、抽象类:除了使用虚函数,C++ 中还可以使用抽象类实现多态。抽象类是一种不能被实例化的类,它通常包含至少一个纯虚函数,纯虚函数在基类中声明时没有函数体,在派生类中必须被重写。由于抽象类不能被实例化,因此派生类必须实现所有纯虚函数才能被实例化

#include <iostream>
class Shape {
public:
  virtual void draw() = 0;
};

class Rectangle : public Shape {
public:
  void draw() override {
    std::cout << "Drawing rectangle...\n";
  }
};

class Circle : public Shape {
public:
  void draw() override {
    std::cout << "Drawing circle...\n";
  }
};

int main() {
  Shape* shapes[2];
  shapes[0] = new Rectangle();
  shapes[1] = new Circle();

  for (int i = 0; i < 2; i++) {
    shapes[i]->draw();
  }

  return 0;
}

9、初始化与赋值的区别

        初始化的含义是在创建对象时赋予一个初值。
        赋值的含义是将对象的当前值擦除掉,以一个新值代替。        
        区分方式:在对象创建时赋予值,叫初始化,否则即为赋值。
        C++语言的初始化方式(以类类型为例)
                <1>:直接初始化:调用的是与实参匹配的构造函数
                <2>:拷贝初始化:调用的是拷贝构造函数 
 



 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/646026.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

仓储管理小程序开发 实现不同行业不同规模的仓管需求

在电子商务快速发展的时代&#xff0c;仓库管理对于一个企业的经营发展来说至关重要。如今互联网技术深入发展&#xff0c;很多企业都开发了信息化管理系统&#xff0c;仓库管理APP小程序就是企业结合自身的运算法则开发的一款线上应用软件&#xff0c;通过智能智慧仓库内人、物…

网络安全是一个好的专业吗?高考之后怎么选择?

目录 一.始于大学 二.一路成长 三. 如何学习网络安全 学前感言 零基础入门 尾言 本人信息安全专业毕业&#xff0c;在甲方互联网大厂安全部与安全乙方大厂都工作过&#xff0c;有一些经验可以供对安全行业感兴趣的人参考。 或许是因为韩商言让更多人知道了CTF&#xff0…

linuxOPS基础_LAMP开源项目实战

LAMP概述 LAMP&#xff1a;Linux Apache MySQL PHP LAMP 架构&#xff08;组合&#xff09; LNMP&#xff1a;Linux Nginx MySQL php-fpm LNMP 架构&#xff08;组合&#xff09; LNMPA&#xff1a;Linux Nginx(80) MySQL PHP Apache Nginx 代理方式 Apache&#…

Markdown编辑器使用

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

这所Top3顶尖院校,专业课太简单了,比双非还要简单!

一、学校及专业介绍 复旦大学&#xff08;FDU&#xff0c;简称旦旦&#xff09;&#xff0c;除清北之外的顶尖学府&#xff0c;想必不用我过多介绍&#xff0c;Top3之一&#xff08;众所周知&#xff0c;Top3有好多所图片&#xff0c;但我心目中的Top3永远是上海交大图片&#…

element-ui中表头添加自定义按钮以及其他自定义展示

可以使用&#xff1a;render-header方法即可 添加一个按钮如下&#xff1a; renderHeader (h) { return ( <div> <span>操作</span> <el-button type"primary" style"margin-left:90px" size"small" icon"el-icon-pl…

在测试外包干了4年,我废了...

外包公司值不值得去&#xff0c;是很多同行关心的话题。在职场一直流传着“外包不被当人看”“外包没有归属感”的言论。 客观来看&#xff0c;外包岗位确实存在一些缺点&#xff0c;比如&#xff1a;公积金&#xff0c;社保缴纳基数低&#xff0c;没有稳定的涨薪通道&#xff…

登录时token的存储

1.token是什么&#xff1f; 是一种身份的标识,比如我们入住一家酒店,他会给我们一张房卡,房卡的期限是有时间限制的,只有持有房卡的人才能入住酒店。 2.jsCookie 使用的方法 下包: npm i jscookie 导入: import Cookiejs from "js-cookie"; 使用: Cookie.js.set…

object类clone、finalize

2 什么是API API&#xff08;Application Programming Interface&#xff0c;应用程序接口&#xff09;是一些预先定义的函数。目的是提供应用程序与开发人员基于某软件可以访问的一些功能集&#xff0c;但又无需访问源码或理解内部工作机制的细节. API是一种通用功能集,有时公…

HTB-OnlyForYou

HTB-OnlyForYou 信息收集立足johnjohn -> root 信息收集 Designed by BootstrapMade. 在他们的TEAM的常见问答里面发现了一个beta产品。 网站首页可以下载疑似源码的文件。 右上角还有两个功能。 一个是上传图片并调整大小。 上传了文件后会跳转到list&#xff0c;选择…

【CV大模型SAM(Segment-Anything)】如何一键分割图片中所有对象?并对不同分割对象进行保存?

之前的文章【CV大模型SAM&#xff08;Segment-Anything&#xff09;】真是太强大了&#xff0c;分割一切的SAM大模型使用方法:可通过不同的提示得到想要的分割目标,中详细介绍了大模型SAM&#xff08;Segment-Anything&#xff09;根据不同的提示方式得到不同的目标分割结果。 …

11. 100ASK-V853-PRO开发板 RGB屏测试指南

100ASK-V853-PRO开发板 RGB屏测试指南 硬件要求&#xff1a; 100ASK-V853-PRO开发板七寸RGB屏 软件要求&#xff1a; 固件下载地址&#xff1a;链接&#xff1a;百度网盘 提取码&#xff1a;sp6a 固件位于资料光盘中的10_测试镜像/1.测试七寸RGB屏/v853_linux_100ask_uart0.…

echarts中国地图使用整理

一、echarts中国地图使用案例 1.准备地图数据china.json ; 需要的添加微信&#xff1a;tianma104&#xff0c;我发你 2.引入jquery&#xff0c;引入eachars 库 <script src"http://xx/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script s…

Unity入门5——Camera

一、参数面板 二、参数介绍 1. Clear Flags&#xff1a;清除背景 Skybox&#xff1a;天空盒背景&#xff08;通常用来做 3D 游戏&#xff09; Solid Color&#xff1a;使用 Background 颜色填充&#xff08;通常设置为全黑或全白&#xff0c;2D 使用&#xff09; Depth Only&am…

【ARM AMBA ATB 入门 1 - ATB 总线简介】

文章目录 背景1.1 ATB BUS1.2.1 全局信号1.2.2 数据信号1.2.3 流控信号1.2.4 Trace ID1.2.5 Buffer Flusing 背景 在 AMBA3 中&#xff0c;增加了 Advanced Trace Bus (ATB) 总线作为片上调试的总线接口&#xff0c;为 Debug 和 Trace 提供一种解决方案。第3代总线是2003年发布…

存储快速入门——【1】网络存储主要技术(NAS、SAN、SCSI、CIFS、zone)

存储快速入门——【1】网络存储主要技术 1 NAS简介&#xff08;网络&#xff09; 在20世纪80年代初&#xff0c;英国纽卡斯尔大学布赖恩.兰德尔教授 ( Brian Randell)和同事通过“纽卡斯尔连接”成功示范和开发了在整套UNIX机器上的远程文件访问。继“纽卡斯尔连接”之后&…

Springboot集成Redis常见的报错和解决方案

Springboot集成Redis后运行时常见的报错信息和其解决方案 1. io.lettuce.core.protocol.CommandHandler : null Unexpected exception during request: java.io.IOException: 远程主机强迫关闭了一个现有的连接。报错信息原因分析解决方案 2. io.netty.util.internal.OutOfDire…

Python自动化测试 史上最全的进阶教程

Python自动化测试就是把以前人为测试转化为机器测试的一种过程。自动化测试是一种比手工测试更快获得故障反馈的方法。 随着时代的变革&#xff0c;也许在未来测试这个职位的需求会越来越少甚至消失&#xff0c;但是每一个组织&#xff0c;每一个客户对软件质量的要求是永远不…

剪辑软件生成的mp4素材无法打开的修复方法

专业剪辑软件可以对视频、音频进行各种修改、美化&#xff0c;像adobe的PR等。今天我们来看一个剪辑软件生成的视频无法打开的修复案例&#xff0c;看看遇到这种情况如何处理. 故障文件:273M和1.72G两个文件 故障现象: 剪辑完成后保存到移动硬盘&#xff08;文件系统为exfat…

VALSE 2023 无锡线下参会个人总结 6月10日-1

VALSE2023无锡线下参会个人总结6月10日-1 会场照片6月10日会议日程安排大会主旨报告&#xff1a;高文&#xff1a;特征编码与数字视网膜焦李成&#xff1a;下一代深度学习的思考与若干问题陈熙霖&#xff1a;计算机视觉-从孤立到系统性方法 企业宣讲环节&#xff08;一&#xf…