C++ DAY7

news2025/1/13 2:48:21

一、类模板

建立一个通用的类,其类中的类型不确定,用一个虚拟类型替代

template<typename T>
类

template ----->表示开始创建模板
typename -->表明后面的符号是数据类型,typename 也可以用class代替
T  ----->表示数据类型,可以其他符号代替

使用类模板的时候,需要表明模板参数类型

#include <iostream>

using namespace std;

//声明创建类模板
template <typename T, typename N>
class A
{
private:
    T n;
    N b;
public:
    A(){}

    A(T n, N b):n(n),b(b){}

    void show()
    {
        cout << n << endl;
        cout << b << endl;
    }
};

int main()
{
    A<string,int> a("zhangsan",1001);//使用类模板的时候,需要表明模板参数类型
    a.show();

    A<int, char> b(34,'w');
    b.show();

    return 0;
}

二、异常

更优雅的解决代码中的问题和异常,可以发现异常并处理进行分开

#include <iostream>


using namespace std;


int fun(int a, int b)
{
    if(b!=0)
    {
        return a/b;
    }
    else
    {
        throw -1;
    }
}


int main()
{
    try{
        fun(9,0);  //把可能出现异常的代码用try包裹起来
        cout << "hello world" << endl;
    }catch(int e)
    {
        if(e == -1)
        {
            cout << "分母不能为0" << endl;
        }
    }
    return 0;
}

三、auto关键字

用来修饰变量,作为自动类型推导,推导出变量的数据类型

注意

1> 使用auto修饰变量时,必须初始化

2> auto的右值,可以是右值,也可以是表达式,还可以是函数的返回值

3> auto不能直接声明数组

4> auto不能作为函数的形参

5> auto不能修饰非静态成员

主要用于修饰冗长的数据类型,使用在函数模板中,依赖模板参数的变量。

四、lambda表达式

当你需要一个匿名的、临时的、需要获得外界变量的函数时,可以用lambda来完成。

#include <iostream>

int main() {
    int a = 1, b = 2;
    
    // 值捕获
    auto sum1 = [a, b]() { return a + b; };
    std::cout << "sum1: " << sum1() << std::endl;
    
    // 引用捕获,由于是引用,出了作用域也会修改a、b值
    auto sum2 = [&a, &b]() { return a + b; };
    std::cout << "sum2: " << sum2() << std::endl;
    
    // 混合捕获
    auto sum3 = [a, &b]() { return a + b; };
    std::cout << "sum3: " << sum3() << std::endl;
    
    // 值捕获,但使用mutable使其可修改 出了作用域后不修改值
    auto sum4 = [a, b]() mutable { a = a + 1; return a + b; };
    std::cout << "sum4: " << sum4() << std::endl;
    
    // 指定返回类型
    auto sum5 = [a, b]() -> int { return a + b; };
    std::cout << "sum5: " << sum5() << std::endl;
    
    return 0;
}

五、数据库类型转换

1>隐式类型转换(自动类型转换)

这是C++编译器自动执行的类型转换,通常在表达式中出现时发生。例如,将较小的整数转换为较大的整数类型,将整数提升为浮点数等。

2>显示类型转换(强制类型转换)

通过使用强制类型转换操作符来显示执行类型转换。这种转换可能会导致数据的截断或者精度丢失,因此要小心使用。

(1)静态转换(static_cast)

用于基本数据类型之间的转换

以及父类指针/引用转换为子类指针/引用

还可以用于不同类型的指针之间的转换

double num_double = 3.14;
int num_int = static_cast<int>(num_double);  // 显式将double转换为int

(2)动态转换(dynamic_cast)

通常用于多态类之间的指针或引用类型转换,确保类型安全。在运行时进行类型检查,只能用于具有虚函数的类之间的转换

class Base {
    virtual void foo() {}
};
class Derived : public Base {};

Base* base_ptr = new Derived;
Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);  // 显式将基类指针转换为派生类指针

(3)常量转换(const_cast)

用于添加或移除指针或引用的常量性。它可以用来去除const限定符,但要注意潜在的未定义行为

const int a =10; //
int *p;
p = &a; // 合不合法?   no
        //如果能这样使用,那就可以通过指针取值去改const修饰的值了,这就和const修饰相悖了
**************************************

const int num_const = 5;
int* num_ptr = const_cast<int*>(&num_const);  // 去除const限定符

(4)重新解释转换(reinterpret_cast)

执行低级别的位模式转换,通常用于指针之间的类型转换。它可能导致未定义行为,因此要谨慎使用

int num = 42;
float* float_ptr = reinterpret_cast<float*>(&num);  // 重新解释转换

3>c风格类型转换

可以使用C样式转换

int num_int = 10;
double num_double = (double)num_int;  // C样式强制类型转换

函数样式转换:C++中使用的类型转换

int num_int = 10;
double num_double = double(num_int);  // C++函数样式类型转换

在使用强转的时候要注意潜在问题和错误,保证操作是安全的。

关键字总结

 63个关键字,红色(不包括class,class是修改之前的错误)的32个是c中的关键字

1>
asm
1:这是一个用于嵌入汇编语言代码的关键字。它允许你在C++代码中直接插入汇编指令,通常用于执行特定的底层操作。然而,由于现代C++提供了更强大的抽象和跨平台性,通常不建议使用这个关键字。
explicit
2:这个关键字通常用于禁止隐式类型转换的发生。当一个构造函数被声明为explicit时,它将不会在隐式类型转换中被调用,只能在显式构造函数调用中使用。
export
3:在C++中,export关键字用于指示一个模板的定义将在另一个文件中实例化。然而,在实际的C++标准中,export关键字的语法并未最终确认,并且在许多编译器中也未被实现。在C++20中,export被重新引入,但是它的主要用途是与模块化编程相关,而不是之前模板实例化的用法。
goto
4:goto是一个跳转语句,允许你无条件地将程序的控制转移到指定的标签处。然而,由于使用goto会导致代码结构变得混乱和难以维护,现代编程实践通常建议避免使用它。
register
5:在早期的C语言标准中,register关键字用于建议编译器将变量存储在寄存器中,以便提高访问速度。然而,现代编译器已经能够智能地管理寄存器分配,所以使用register关键字通常不再有明显的性能提升,并且在C++17中已被弃用。
volatile
6:volatile关键字用于告诉编译器不要对标记为volatile的变量进行优化,因为这些变量的值可能会在未知的时间被外部因素改变,比如硬件中断或多线程环境中的共享变量。这可以防止编译器对这些变量的读取和写入操作进行优化,以确保程序的行为是可预测的。


2>    数据类型相关的关键字
bool、true、false:对于bool类型数据的相关处理,值为true和false
char、wchar_t:char是单字符数据,wchar_t多字符数据
int、short、float、double、long:整数和实数的数据类型
signed、unsigned:定义有符号和无符号数据的说明符
auto:在c语言中,是存储类型,但是在C++中,是类型自动推导,注意事项有两个:
i>    连续定义多个变量时,初始值必须是相同数据类型,否则报错
ii>    auto p=&m;  与auto* p = &m;规定是一样
explicit:防止数据隐式转换
typedef:类型重定义
sizeof:求数据类型的字节运算


3>    语句相关的关键字
switch、case、default:实现多分支选择结构
do、while、for:循环相关的关键字
break、continue、goto:跳转语句
if、else:选择结构
inline:内联函数
return:函数返回值


4>    存储类型相关的关键字
static、const、volatile、register、extern、auto


5>    构造数据类型相关
struct、union:结构体和共用体
enum:枚举
class:类


6>    访问权限:public、protected、private


7>    异常处理:throw、try、catch


8>    类中相关使用关键字
this:指代自己的指针
friend:友元
virtual:虚
delete、default:对类的特殊成员函数的相关使用
例如:Test(const Test &) = default;    ~Test()  = delete;
mutable:取消常属性
using:引入数据,有三种使用方式
i>    使用命名空间的关键字
ii> 相当于类型重定义
iii> 修改子类中从父类继承下来成员的权限
operator:运算符重载关键字


9>    类型转换相关的关键字
static_cast、dynamic_cast、const_cast、reinterpret_cast


10>    模板相关的关键字:template、typename


11>    命名空间相关:using、namespace


12>    export:导入相关模板类使用


13>    内存分配和回收:new、delete

六、C++标准模板库(STL)

标准模板库中使用了大量的函数模板和类模板,来对数据结构和算法的处理。

STL主要由 容器、算法、迭代器组成。

容器:置物之所也

数组、链表、队列、栈、集合。。。

算法:问题之解法也

增、删、改、查

迭代器:是容器和算法之间的粘合剂 (== 指针)

6.1vector

类似于数组、也可称之为单端数组

和普通数组的区别:普通数组是静态空间,vector是动态拓展。

动态拓展:不是在原来空间后续接空间,而是重新申请更大的空间,将原来的数据拷贝到新的空间中。

vector的构造函数

        vector v;//无参构造

        vector(v.begin(),v.end()); //将区间[begin(),end()),拷贝给本身

        vector(const vector& v); //将v拷贝给本身

        vector(n, elem) ; //将n个elem拷贝给本身

#include <iostream>
#include <vector>

using namespace std;

//算法
void printVector(vector<int> &v)
{
    vector<int>::iterator iter; //定义了这样容器类型的迭代器
    for(iter = v.begin(); iter != v.end(); iter++)
    {
        cout << *iter << " ";
    }
    cout << endl;
}

int main()
{
    //容器
    vector<int> v; //无参构造函数
    v.push_back(10); //尾插
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);

    //算法
    printVector(v);

    vector<int> v2(v.begin(),v.end());
    printVector(v2);

    vector<int> v3(6,100);
    printVector(v3);

    vector<int> v4 = v3;
    printVector(v4);


    vector<int> v5(v2);
    printVector(v5);

    return 0;
}

vector的赋值函数

        vector &operator = (const vector &v);//将v赋值给本身

        assign(beg,end); //将区间[begin(),end())赋值给本身

        assign(n, elem); //将n个elem赋值给本

vector容量大小

        empty(); //判断容器是否为空

        capacity() ; //计算容器的容量大小

        size(); //计算容器大小 ---- 容器的元素个数

        resize(); //重新设置大小

vector的插入和删除 

        push_back(); //尾插

        pop_back(); //尾删

        insert(iterator pos,elem) //在迭代器指向的位置,插入数据

        insert(iterator pos,n, elem) //在迭代器指向的位置,插入n个数据

        erase(iterator pos); //删除迭代器指向元素

        erase(iterator start, iterator end); //删除区间的元素

        clear() ; //删除容器中所有的元素

vector的元素提取

        at(int idx);

        operator[](int idx);

        front(); //返回第一个元素

        back(); //返回最后一个元素

七、文件操作

        由于程序运行时的数据都是历史数据,程序一旦结束,数据就会消失

头文件: #include<fstream>

文件操作的三大类

读文件:ifstream

写文件:ofstream

读写:fstream

7.1写入数据

1.包含头文件

#include

2.创建流对象

ofstream ofs;

3.打开文件

ofs.open("文件名",打开方式);

4.写入数据

ofs

5.关闭文件

ofs.close();

7.2读文件

1.包含头文件

#include

2.创建流对象

ifstream ifs;

3.打开文件

ifs.open("文件名",打开方式);

 

试编程:

封装一个学生的类,定义一个学生这样类的vector容器, 里面存放学生对象(至少3个)

再把该容器中的对象,保存到文件中。

再把这些学生从文件中读取出来,放入另一个容器中并且遍历输出该容器里的学生。

#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;

class Stu {
private:
    int classnum;
    int grade;
    string name;
public:
    Stu() {}
    Stu(int class_num, int grade, string name) : classnum(class_num), grade(grade), name(name) {}
    void set(int i, int g) {
        classnum = i;
        grade = g;
    }
    void name_set(string n) { name = n; }
    friend void ofs(vector<Stu>& p);
};

void ofs(vector<Stu>& p) {
    ofstream ofs;
    ofs.open("F:/test.txt", ios::out);
    for (const auto& student : p) {
        ofs << student.classnum << ' ' << student.grade << ' ' << student.name << endl;
    }
    ofs.close();
}

int main() {
    vector<Stu> p;
    for (int i = 0, j = 1; i < 2; i++, j++) {
        Stu student;
        student.set(i, j);
        if (0 == i) {
            student.name_set("lisi");
        } else if (1 == i) {
            student.name_set("zhangsan");
        }
        p.push_back(student);
    }

    ofs(p);

    return 0;
}

list相关函数

#include <iostream>
#include <list>

int main() {
  // 默认构造函数
  std::list<int> lst1;

  // 初始化列表构造函数
  std::list<int> lst2 = {1, 2, 3};

  // 拷贝构造函数
  std::list<int> lst3(lst2);

  // 填充构造函数
  std::list<int> lst4(3, 10);  // 3个元素,每个元素都是10

  // 赋值操作
  lst1 = lst2;

  // assign函数
  lst1.assign({4, 5, 6});
  lst2.assign(3, 7);  // 3个元素,每个元素都是7

  // 输出lst1
  for (std::list<int>::iterator it = lst1.begin(); it != lst1.end(); ++it) {
      int x = *it;
      std::cout << x << ' ';
  }
    std::cout<<std::endl;
  // 输出lst2
  for (std::list<int>::iterator it = lst2.begin(); it != lst2.end(); ++it) {
      int x = *it;
      std::cout << x << ' ';
  }

  return 0;
}

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

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

相关文章

php开发环境搭建_宝塔、composer

宝塔面板下载&#xff0c;免费全能的服务器运维软件 一 下载宝塔面板 解压安装 登录之后修改安全入口 1 进入软件商店下载nginx,mysql5.6,php7.2 2 将php的安装路径配置到环境变量中 此电脑--右键--点击属性---高级系统设置---环境变量---系统变量path---添加确定 输入php -v…

DC/DC开关电源学习笔记(三)开关频率和储能元件

&#xff08;三&#xff09;开关频率和储能元件 1.开关频率2.储能元件 1.开关频率 频率是开关电源的一个基本属性&#xff0c;它代表了直流电压开启和关断的速率。了解开关频率就可以了解实际应用中电源线路的工作原理。 开关电源利用开关动作将直流电转换为特定频率的脉冲电…

【教程】部署apprtc服务中安装google-cloud-cli组件的问题及解决

前置条件 已经安装完成node&#xff0c;grunt&#xff0c;node 组件和python pip包等。需要安装google-cloud-cli组件。 Ubuntu安装google-cloud-cli组件 apprtc项目运行需要google-cloud-cli前置组件&#xff0c;且运行其中的dev_appserver.py。 根据google官方的关于安装g…

应用于伺服电机控制、 编码器仿真、 电动助力转向、发电机、 汽车运动检测与控制的旋变数字转换器MS5905P

MS5905P 是一款 12bit 分辨率的旋变数字转换器。 片上集成正弦波激励电路&#xff0c;正弦和余弦允许输入峰峰值 幅度为 2.3V 到 4.0V &#xff0c;可编程激励频率为 10kHz 、 12kHz 、 15kHz 、 20kHz 。 转换器可并行或串行输出角度 和速度对应的数字量。 MS5905…

第 3 章 栈和队列(顺序栈,算法 3.1 、3.2、3.4)

1. 示例代码&#xff1a; 1) status.h /* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H #define STATUS_H/* 函数结果状态码 */ #define TRUE 1 /* 返回值为真 */ #define FALSE 0 /* 返回值为假 */ #define RET_OK 0 /* 返回值正确 */ #d…

Python Opencv实践 - Canny边缘检测

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_GRAYSCALE) print(img.shape)#图像Canny边缘检测 #cv.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradien…

【第1章 数据结构概述】

目录 一. 基本概念 1. 数据、数据元素、数据对象 2. 数据结构 二. 数据结构的分类 1. 数据的逻辑结构可分为两大类&#xff1a;a. 线性结构&#xff1b;b. 非线性结构 2. 数据的存储结构取决于四种基本的存储方法&#xff1a;顺序存储、链接存储、索引存储、散列存储 3. …

【Unity】终极移动指南-注解【理解移动到抓钩,再到贪吃蛇的实现】

文章目录 【Unity】终极移动指南-注解&#xff08;从移动、抓钩到贪吃蛇&#xff09;观前提醒链接地址&#xff1a; 内容一、 transform移动操作【1】transform.position变换位置【2】transform.Translate平移【3】transform.position 类似平移的操作【4】定向矢量【5】停在指定…

教你快速记单词。一套高效的单词记忆法,背单词技巧 英语没有一个单词需要死记硬背的,5天能不能记住1万个单词 CrazyEnglish视频学习

就是这些辅音是可以互换的&#xff0c;之后我们就是换元音来组成新的单词 整个欧洲基本说的都是方言&#xff0c;他们很多真的就是发音和书写在变 这张图片超级重要 其实跟我们小时候学的那个拼音的那个背记排序好像是一样的 &#xff08;看到这个视频的后面&#xff0c;你就…

Linux操作系统中特定软件的安装

Linux中特定软件的安装 1、yum仓库2、在Linux中安装JDK3、在Linux中安装MySQL4、VMware的安装5、在VMware中安装CentOS6、克隆虚拟机 1、yum仓库 yum install -y 安装包的名字 更换yum的base源&#xff1a; /etc/yum.repos.d/CentOS-Base.repo 1、需要把原先的数据源做一个备…

算法题打卡day45-背包问题 | 70. 爬楼梯 (进阶)、322. 零钱兑换、279.完全平方数

70. 爬楼梯 - 力扣&#xff08;LeetCode&#xff09; 状态&#xff1a;查看思路后AC。 除了常规的可以爬一或二级台阶&#xff0c;当题目稍微修改一下&#xff0c;变成可以爬m级台阶&#xff0c;之前的DP思路就有局限&#xff08;dp[i] dp[i-1] dp[i-2&#xff09;&#xff0…

SpringAOP详解(下)

proxyFactory代理对象创建方式和代理对象调用方法过程&#xff1a; springaop创建动态代理对象和代理对象调用方法过程&#xff1a; 一、TargetSource的使用 Lazy注解&#xff0c;当加在属性上时&#xff0c;会产生一个代理对象赋值给这个属性&#xff0c;产生代理对象的代码为…

《向量数据库指南》——大模型时代向量数据库是刚需吗?

目录 从实际应用的角度来看 从技术发展的角度来看 如果你问我,我会毫不犹豫地回答:“是的,向量数据库是刚需。”为什么?听我慢慢给你解释。 首先,我们要理解什么是向量数据库。向量数据库是一种专门用于存储和查询向量数据的数据库。这些向量数据可以是文本、图像、音频…

基础数据结构:数组介绍

程序设计 数据结构算法 基本概念和术语 说到数据结构是什么&#xff0c;我们得先来谈谈什么叫数据。 正所谓"巧妇难为无米之炊’&#xff0c;再强大的计算机&#xff0c;也是要有"米’下锅才可以的&#xff0c;否则就是一堆破铜烂铁 这个"米"就是数据。…

【进程间通信】信号

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

vsftpd使用遇到的问题

1.正常创建 安装到配置 yum install -y vsftpd systemctl start vsftpd useradd -d /home/ftpuser ftpuer passwd ftpuser vim /etc/vsftpd/vsftpd.conf i chroot_local_userYES allow_writeable_chrootYES chroot_list_enableYES chroot_list_file/etc/vsftpd/chroot_list2.连…

【计算机网络】序列化与反序列化

文章目录 1. 如何处理结构化数据&#xff1f;序列化 与 反序列化 2. 实现网络版计算器1. Tcp 套接字的封装——sock.hpp创建套接字——Socket绑定——Bind将套接字设置为监听状态——Listen获取连接——Accept发起连接——Connect 2. 服务器的实现 ——TcpServer.hpp初始化启动…

UDP 多播(组播)

前言&#xff08;了解分类的IP地址&#xff09; 1.组播&#xff08;多播&#xff09; 单播地址标识单个IP接口&#xff0c;广播地址标识某个子网的所有IP接口&#xff0c;多播地址标识一组IP接口。单播和广播是寻址方案的两个极端&#xff08;要么单个要么全部&#xff09;&am…

商城系统以拼团、砍价、分销为场景的用户增长,裂变和转化才是关键

其实&#xff0c;用户增长是一个非常大的话题。 用户增长不再是传统互联网意义上&#xff0c;一味地追求用户数量上的增长。用户增长是不断的提出增长假设&#xff0c;通过做实验与数据分析&#xff0c;验证假设的正确性&#xff0c;以此循环往复&#xff0c;反复迭代&#xf…