C++ 学习笔记(三)—— 入门+类和对象

news2025/3/19 20:48:51
1、内联函数(inline)

内联函数主要是解决C语言的宏的缺陷提出来的;

宏的缺陷:

1)容易出错,语法坑很多;

2)不能调试;

3)没有类型安全的检查;

宏的优点:

1)没有类型的严格限制;

2)针对频繁调用小函数,不需要再建立栈帧,提高了效率;

// 内联函数的使用示例
inline int add(int x, int y)
{
    return x + y;
}

int main()
{
    add(1, 2);  // 在debug模式下不会展开,方便调试;
    // 但是在release版本下可以展开;
    // 不像宏一样只是单纯的替换,减少了语法坑;
    // 内联函数虽然有诸多好处,但是容易导致目标文件过大,因此一般只将很小的函数设为内联;
    // 有一些编译器会自动识别,过大和递归的函数设置为内联会被编译器忽略;

    // 内联函数不能声明和定义分离;
    // 因为内联是在汇编的时候就已经要展开了,如果声明和定义分离就要在机器语言链接的时候才能关联;
    // 链接的符号表里内联函数不会存在,编译器也默认在之前就已经展开了;
    // 因此会报链接错误;
}
2、C++11语法糖
1)auto

根据等式右边的值自动推导左边的值的类型;该方案在常规情况下价值比较低,只有在类型名字很长的时候才能体现它的价值;

比如:std:: vector<std::string>::iterator oo = v.begin();  ——>auto oo = v.begin();

但需要注意auto不能作为函数的参数也不能用来声明数组;

小扩展:

如果用着用着不记得类型是啥了,可以通过typeid(变量).name()返回类型字符串;

2)范围for
int main()
{
    int array[] = {1, 2, 3, 4, 5};
    // 传统遍历数组的方法
    for(int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
        cout<< array[i] << " ";
    cout << endl;
    // 范围for用法
    // 这里是把array里的值赋值给e哦,所以改变e是不会改变array里面的值的;
    for(auto e : array)  // 这里不是非得用auto,用int也可以,只是auto比较通用比较方便
    {
        cout << e << " ";
    }
    cout << endl;
        return 0;
}

void func(int array[])
{
    // 此处会报错哦,因为此处array看起来是数组,其实是指针啦,范围for不支持;
    for(auto e : array)  
    cout << e << endl;
}
3)空指针nullptr

NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到:

#define NULL 0   (C++自己定义的,C语言没有)

因此在有些地方,会被识别为字面常量0,也容易导致一些错误的出现,如:

void func(int p)
{
    cout << "int" << endl;
}

void func(int* p)
{
    cout << "int*" << endl;
}

func(NULL);  // 此处会显示“int”而不是“int*”
//为了解决这种错误,引入nullptr代表空指针;
3、 类和对象

之前有说过,在C++中兼容的结构体,本质上已经升级为了类,但是纯正的类,更喜欢用class作为定义类的关键字;而且,struct和class还是有一定的区别的,主要就是在访问限定符的使用上。

1)访问限定符

访问限定符:public(公有)、protected(保护)、private(私有)【目前暂时可以将保护和私有看作是一样的】——公有在类的外面可以访问,保护和私有只能在类里面访问;

class Stack
{
// 成员函数
void Init()
{
    a =nullptr;
    top = capacity = 0;
}

void Push(int x)
{
// 扩容判断
    if(top = capacity)
    {
        size_t newcapacity = capacity == 0 ?4 : capacity * 2;
        a = (int* )realloc(a, sizeof(int)*newcapacity);
        capacity = newcapacity;
    }

    // 插值
    a[top++] = x;
}

    // 成员变量
    int* a;
    int top;
    int capacity;
}

int main()
{
    Stack ss;
    ss.Init();
    ss.Push(1);  // 此处都会报错哦,error:访问私有数据;
    //  修改的方法,要不然把class改成struct,要不然就在需要外部访问的成员前加”public:”修饰;
    //  访问限定符的修饰范围是从访问限定符开始到下一个访问限定符/结束;
    //  class的默认访问限定是私有的哦,所以没有加public都是私有的都不能访问哦~
    //  访问限定符只限制类外访问,类中访问无限制;
    return 0;
}

// 类也可以声明和定义分离
// test.h
class Stack
{
public:
    // 成员函数
    void Init();
    void Push(int x);
private:
    // 成员变量
    int* a;
    int top;
    int capacity;
}

//  test.cpp
void Stack::Init()
{
    a =nullptr;
    top = capacity = 0;
}

void Stack::Push(int x)
{
    // 扩容判断
    if(top = capacity)
    {
        size_t newcapacity = capacity == 0 ?4 : capacity * 2;
        a = (int* )realloc(a, sizeof(int)*newcapacity);
        capacity = newcapacity;
    }
    // 插值
    a[top++] = x;
}

小扩展:
1)之前有提到过,一个语句如果要用一个函数或者一个变量,都是去之前的也就是上面的语句中查找,如果需要用到的函数或者变量在这个语句之后定义,就会出现找不到的情况,这种的话需要提前写一个声明才可以。
但是类里面的话,我们一般习惯把成员函数写在上面,成员变量写在下面,这种写法却不会出现找不到的情况,因为类是一个整体,所以里面的变量和函数无关顺序;
2)还需要注意,在类里面定义的成员函数默认就是内联函数,这一点后面会具体说;
3)成员的命名习惯:为了避免引用参数和成员变量同名导致错误的产生,比如时间类:

class Date
{
public:
    void Init(int year, int month, int day)
    {
    year = year;  //  此处虽然不会报错,但是也并不会被正确的初始化,因为局部优先,会变成参数自己赋            值给自己,而不会赋值给成员变量
    //  因此,成员变量一般命名为“_year”、"year_";该方法虽然不是必须的,但是是约定俗成的;
    }
private:
    int year;
    int month;
    int day;
}
2)类的作用域

类定义了一个新的作用域,类的所有成员都在类的作用域中。在类外定义成员时,需要使用::作用域操作符指明成员属于哪个类域;——  这个在声明和定义分开的部分已经举过例子了;

// 以下脑洞大开的用法
class Date
{
public:
    void Init(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
}

int main()
{
    Date::_year;
    Date._year;  //  都是非法语句哈
    //  因为类里面的成员变量设置的地方只是一个声明,不是定义;
    //  无法访问一个声明里面的变量;
}
3)类的实例化

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

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

相关文章

基于 SSE 和 WebSocket 的在线文本实时传输工具

简介 在线文本实时传输工具支持 SSE&#xff08;Server-Sent Events&#xff09; 和 WebSocket&#xff0c;可在不同设备间快速共享和同步文本&#xff0c;适用于跨设备协作、远程办公和即时通讯。 核心功能 实时同步&#xff1a;文本输入后&#xff0c;另一端用户可立即看到…

数图亮相第三届全国生鲜创新峰会,赋能生鲜零售数字化转型

2025年3月15-18日&#xff0c;第三届全国生鲜创新峰会在湖北宜昌召开&#xff0c;主题为“生鲜破局&#xff0c;重塑价值”。峰会汇聚行业专家、企业领袖及精英&#xff0c;探讨生鲜零售新机遇与挑战。作为领先的“智慧零售”服务商&#xff0c;数图信息科技受邀出席&#xff0…

go 安装swagger

1、依赖安装&#xff1a; # 安装 swag 命令行工具 go install github.com/swaggo/swag/cmd/swaglatest# 安装 gin-swagger 和 swagger 文件的依赖 go get -u github.com/swaggo/gin-swagger go get -u github.com/swaggo/files 2、测试 cmd中输入&#xff1a; swag -v 3、…

CH347使用笔记:CH347结合STM32CubeIDE实现单片机下载与调试

目录 基于 STM32CubeIDE的 CH347 JTAG/SWD调试器使用说明1. CH347驱动安装与配置2. STM32CubeIDE调试器配置2.1 打开相关工程后&#xff0c;进行以下操作2.2 openocd.exe替换2.3 脚本添加2.4 更改调试器选择 3. 下载程序4. 使用过程中可能遇到的问题4.1 CH347未插入4.2 Openocd…

从C语言开始的C++编程生活(1)

前言 本系列文章承接C语言的学习&#xff0c;需要有C语言的基础才能学会哦。 第1篇主要讲的是有关于C的命名空间、输入和输出。 C才起步&#xff0c;都很简单呢&#xff01; 目录 前言 命名空间namespace 基本语法 作用 使用命名空间 域作用限定符 :: 基本语法 using n…

Python F-String 深度解析:原理、用法与最佳实践

# Python F-String 深度解析&#xff1a;原理、用法与最佳实践 ## 一、引言 Python 的 F-String&#xff08;格式化字符串字面值&#xff09;自 3.6 版本引入以来&#xff0c;凭借其简洁性和高效性&#xff0c;迅速成为字符串格式化的首选方案。本文将从原理、核心用法和编码规…

20. Excel 自动化:Excel 对象模型

一 Excel 对象模型是什么 Excel对象模型是Excel图形用户界面的层次结构表示&#xff0c;它允许开发者通过编程来操作Excel的各种组件&#xff0c;如工作簿、工作表、单元格等。 xlwings 是一个Python库&#xff0c;它允许Python脚本与Excel进行交互。与一些其他Python库&#x…

解决uni-app授权弹框华为审核拒绝

背景&#xff1a; 在使用定位、相机、文件、电话&#xff0c;需要用户同意授权时&#xff0c;华为和vivo需要告知用户使用权限目的。 方案&#xff1a; 在uni授权时&#xff0c;弹框告诉授权目的&#xff0c;效果如下&#xff1a; 代码&#xff1a; const perListener {//…

施耐德PLC仿真软件Modbus tcp通讯测试

安装仿真软件&#xff1a;EcoStruxure™ Control Expert - PLC 仿真器 下载地址&#xff1a;https://www.schneider-electric.cn/zh/download/document/EIO0000001719/ 配置CPU&#xff1a; 切换至仿真模式&#xff0c;系统托盘中出现仿真器图标 新建变量test&#xff0c;地址…

1.排序算法(学习自用)

1.冒泡排序 算法步骤 相邻的元素之间对比&#xff0c;每次早出最大值或最小值放到最后或前面&#xff0c;所以形象的称为冒泡。 特点 n个数排序则进行n轮&#xff0c;每轮比较n-i次。所以时间复杂度为O(n^2)&#xff0c;空间复杂度为O(1)&#xff0c;该排序算法稳定。 代码…

vs2017版本与arcgis10.1的ArcObject SDK for .NET兼容配置终结解决方案

因电脑用的arcgis10.1,之前安装的vs2010正常能使用AO和AE&#xff0c;安装vs2017后无法使用了&#xff0c;在重新按照新版本arcgis engine或者arcObject费时费力&#xff0c;还需要重新查找资源。 用vs2017与arc10.1的集成主要两个问题&#xff0c;1&#xff1a;安装后vs中没有…

基于yolo11+flask打造一个精美登录界面和检测系统

这个是使用flask实现好看登录界面和友好的检测界面实现yolov11推理和展示&#xff0c;代码仅仅有2个html文件和一个python文件&#xff0c;真正做到了用最简洁的代码实现复杂功能。 测试通过环境&#xff1a; windows x64 anaconda3python3.8 ultralytics8.3.81 flask1.1.…

用 Vue 3.5 TypeScript 重新开发3年前甘特图的核心组件

回顾 3年前曾经用 Vue 2.0 开发了一个甘特图组件&#xff0c;如今3年过去了&#xff0c;计划使用Vue 3.5 TypeScript 把组件重新开发&#xff0c;有机会的话再开发一个React版本。 关于之前的组件以前文章 Vue 2.0 甘特图组件 下面录屏是是 用 Vue 3.5 TypeScript 开发的目前…

深入解析 SQL 事务:确保数据一致性的关键

SQL 事务 什么是 SQL 事务&#xff1f;事务的 ACID 特性原子性&#xff08;Atomicity&#xff09;:示例&#xff1a; 一致性&#xff08;Consistency&#xff09;:示例&#xff1a; 隔离性&#xff08;Isolation&#xff09;:持久性&#xff08;Durability&#xff09;:示例&am…

基于STM32的火灾报警设备(阿里云平台)

目录 前言&#xff1a; 一、项目介绍和演示视频 二、硬件需求准备 三、硬件框图 1. 原理图 2. PCB 四、CubeMX配置 五、代码框架 前言&#xff1a; 源代码下载链接&#xff1a; https://download.csdn.net/download/m0_74712453/90474701 需要实物的可以私信博主或者…

FPGA-流水灯

Quartus中使用Verilog实现 根据之前所学内容&#xff0c;打开Quartus 软件&#xff0c;新建FPGA项目文件&#xff0c;建立好空项目过后&#xff0c;选择Verilog HDL File&#xff0c;因为我们要使用Verilog代码实现仿真。 详细操作可参考往期博客&#xff1a; FPGA 实验报告&a…

browser-use WebUI + DeepSeek 基于AI的UI自动化解决方案

browser-use WebUI 一、browser-use是什么Browser-use采用的技术栈为&#xff1a; 二、browser-use webui 主要功能使用场景 三、使用教程1.python 安装2、把项目clone下来3、安装依赖4、配置环境5、启动6、配置1.配置 Agent2.配置要用的大模型3.关于浏览器的一些设置 四、Deep…

什么是YApi?开源接口管理平台部署教程

YApi 到底是个啥&#xff1f; 各位小伙伴们好呀&#xff01;今天要给大家介绍的是一款超级好用的接口管理神器——YApi&#xff01;它是一个高效、易用、功能强大的 API 管理平台&#xff0c;简直就是开发、产品、测试人员的福音啊&#xff01;&#xff01;&#xff01;它能帮…

深入理解事务

在数据库管理中&#xff0c;事务是一个至关重要的概念。无论是金融交易、库存管理还是用户数据更新&#xff0c;事务都确保了数据的完整性和一致性。本文将详细介绍为什么需要事务、什么是事务、事务的四大特征、如何在MySQL中使用事务以及MyBatis对事务的配置。 一、为什么需…

基于SpringBoot + Vue 的药店药品信息管理系统

基于SpringBootVue的药品药店药房信息系统(带文档) 角色: 用户&#xff0c;管理员&#xff0c;员工 功能: 管理员: 首页、个人中心、用户管理、员工管理、药品类别管理、药品信息管理、药品入库管理、药品出库管理、在线咨询管理、留言板管理、系统管理、订单管理。 用户:…