C++复习

ops/2025/1/15 8:48:03/

注:本文章所写内容是小编复习所看的。记录的是一些之前模糊不清的知识点。详细c++内容请移步至小编主页寻找。

竞赛小技巧

竞赛中cin/cout用不了(没有办法刷新缓冲区,导致cin/cout与缓冲区绑定)

解决办法:(加以下三行代码)

//或则 换scanf/printf

ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);

类和对象上

namespace命名空间域

不同的域可以定义相同的变量

c++中的域:函数局部域,全局域,命名空间域,类域

::域作用限定符:默认查找全局变量

cout/endl/cin定义在<iostream> iostream 在命名空间域std中

缺省参数

全缺省:每个变量都缺省

半缺省:一部分变量缺省,一部分不缺省(缺省顺序从右向左连续缺省,不能间隔不能跳跃,

传参时从左到右)

缺省函数定义和声明分离时是不能同时出现的(规定)

eg:

stack.h
void Sinit(St*st,int n=100);//生明给
stack.cpp
void Sinit(St*st,int n=200);//不允许
stack.cpp
void Sinit(St*st,int n);//允许

函数重载

要求:同一命名域名(不同命名域名空间域可以有相同函数)

同名函数(不同参数类型或则不同参数个数或不同参数顺序<int,char>//<char,int>)

注:返回值不同不是函数重载

引用

引用的特性

1.引用必须初始化

int& ra;//不清楚是取得谁的别名

2.一个变量可以有多个引用(可以引用引用对象)

3.引用一旦引用一个实体,再不能引用其他实体

引用的使用

注意:做返回值

eg:修改栈顶元素

int SStop(ST& rs){//获取栈顶元素
return rs.a[rs.top-1];
}
SStop=3;//修改不允许  因为返回值返回时会生成一个临时变量(具有常性)不能修改//如果使用引用作返回值(不会产生临时变量直接把数组top位置返回),则可以避免类似情况发生
int& SStop(ST& rs);

const引用

引用const对象必须要用const引用

//错误示范(权限被放大)
/*const int a = 20;
int& ra = a;*/const int a = 10;
const int& ra = a;//正常权限int b = 30;
const int& rb = b;//权限缩小const int& ra=30//常量用const引用const int& rb=(a+b);//(a+b)为临时变狼具有常性 正常权限用const 引用//注:一些计算表达式结过,或则变量类型转换都会产生一个临时变量(临时变量具有常性)

引用和指针的区别

1.引用是给变量取别名(本身不开空间),指针式取变量的地址(指针本身就要开空间)

2.引用必须初始化,指针可以不初始化 。

3.引用只能引用一个对象,指针可以指向多个对象

4.引用直接访问变量,指针需要解引用

5.sizeof(引用变量),sizeof(指针,指针变量 32-4 64-8)

6.引用没有空指针形式,引用可能出现野指针

内联函数(inlline)

适用于频繁调用短小函数

作用:替代宏(#define add(a,b) ((a)+(b))

对于宏替换的目的就是不在建立函数(减少函数栈帧),从而使空间不在浪费。

对于inline函数就是在函数前面添加关键字inline(debug版本下不在在乎性能便于调试默认不展开)

inline int add(){
}

debug版本下调试的方法:(更改项目属性c/c++ 常规为程序数据库,优化改 内敛只适用于inline)

注1:inline函数只是一个建议,对于编译器来讲合理的地方加inline可以展开,不合理的地方加inline编译器也不会展开。

注2:inline函数不建议做声明和变量分离(inline无地址)

nullptr

c语言中NULL的存在是宏替换的存在,define NULL 0

在c++中函数重载时如何传NULL则会出现歧义。

nullptr可以转化成任意类型的指针但不能转化成整形。

类和对象(上)

class{_成员变量成员函数}

class未加访问限定符默认为private,struct默认为public

对于公有和私有简单理解(实例化对象时是否能访问到对应的函数)

对于类成员函数声明和定义分离要指定类域

类域

不同类域可以定义相同名称.

类的实例化

对于类里边的成员变量只是声明(声明是该变量时什么类型,并未开空间)。

对象大小计算

对于类对象大小计算方法:只计算成员变量的大小(每个对象有各自得的成员变量),不计成员函数的大小(成员函数默认放在一个地方,对象调用时调用同一个成员函数)

如果类中没有成员变量那么类对象的大小为1

为什么要内存对齐

cpu读取数据时并不是从任意地方开始读取的,cpu一次性读取指定整数倍位置(如果不对齐则可能数据读取不对)

this指针

this指针实际是做为一个参数(所以this指针存放在栈中)

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class A {
public:void Print() {cout << this << endl;cout << "A.Print()" << endl;}int _a;
};
int main() {A* p = nullptr;p->Print();//p->正常来讲是解引用,但是Print函数并不是在p类中所以该地方并不是解引用,所以不会报错,Print(&p)传nulptr并不是报错p->_a=1;//_a是成员变量需要对指针进行解引用,又因为p是空指针,所以会报错。 return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class A {
public:void Print() {cout << this << endl;cout << "A.Print()" << endl;cout<<_a<<endl//通过this指针访问——athis->a但是this指针为空所以会报错。}private:int _a;
};
int main() {A* p = nullptr;p->Print();//p->正常来讲是解引用,但是Print函数并不是在p类中所以该地方并不是解引用,所以不会报错,Print(&p)传nulptr并不是报错p->_a=1;//_a是成员变量需要对指针进行解引用,又因为p是空指针,所以会报错。 return 0;
}

类和对象中

默认成员函数

构造函数

1.函数名与类名相同,不需要返回值(void也不用),功能:初始化对象)

2.对象实例化时系统会自动调用相应的构造函数。

3.构造函数(有参数构造和无参数构造 构成构造函数函数重载)。

注意:全缺省和无参不能同时存在

4.什么叫默认构造函数?

无参的,全缺省的,我们不写系统默认生成的构造函数成为默认构造函数(在一个类中三者仅且仅能出现一个)。

c++类型分配

a.内置类型(基本类型)int/double

b.用户自定义类型 class/struct 修饰的类型

不写,编译器自动生成的的对内置类型的初始化不确定,对自定义类型如果没有对应的默认构造不进行初始化则会报错。

析构函数(函数销毁)

功能:完成类对像中的资源清理释放

无参数(不能重载),无返回值,与构造函数相反,前边加~

析构顺序:后定义的先析构

拷贝构造函数

规定:拷贝构造函数的第一个参数是对自身类类型的引用,其他任何额外的参数都有默认值,符合以上条件的函数叫拷贝构造函数。

拷贝构造函数的特点:

1.拷贝构造函数是构造函数的一个重载。

2.拷贝构造函数的第一个参数是对自身类类型的引用,如果采用传值传参这则会引发无穷递归。

c++规定:

函数的传值传参需要先调用拷贝构造函数。

贝构造对内置类型完成值拷贝/浅拷贝(一个字节一个字节拷贝),对于自定义类型会调用他的拷贝构造函数。

注意:像日期类这样没有开任何资源空间的类是可以不用自己写拷贝构造函数,但是像栈/队列有开辟新空间的类如果要像完成拷贝必须自己写·。

如下:如果我们不自己写,编译器默认生成的拷贝构造函数,会对栈完成值拷贝/浅拷贝,这样的话拷贝后两块资源同时指向同一个位置,那么析构函数的时候就会释放该空间两次,程序就会崩溃。

解决方法:

重新开一个相同大小的空间,memcpy进行拷贝即可

传值返回与传引用返回

传值返回会产生一个临时对象的拷贝,传引用返回不用产生临时拷贝,但是传引用返回(返回值是全局或则出来出了函数还能找到,如果返回的是函数局部域中的变量,那么 传引用返回时函数栈帧已经销毁,返回的引用就成为野引用)。

赋值重载函数

运算符重载

载,若没有运算符重载则编译会报错。

2.参数个数与运算对象时一一对应的

3.格式:operator + (运算符 )

4.调用方式:a.显示调用 operator+=(Date d1,Date d2);//x1==x2

建议:重载函数放在类里边,第一个参数传给this指针

调用方法:x1.operator==(x2) //x1==x2 x1给this,x2=传一个参数

5.不能重载的运算符:.* :: . sizeof ?:

6.重载运算符至少有一个类类型的参数operator+(int x,int y)//毫无意义 operator+ (Date& d1,int x)//ok

赋值运算符重载

赋值运算符重载是指对已经存在的两个对象进行拷贝赋值

拷贝构造是指一个已经初始化的对象去拷贝另一个没有存在的对象

一元运算符重载
d1++,++d1区分

后置++增加一个int形参

d1++:operator++(int);

++d1: operator();

取地址运算符的重载
const成员函数

const去修饰成员函数把const放在成员函数后边。

简单理解:

实例化对象时如果对象为 const Date d3(2004,4,11);

对象被const修饰,假如去调用类中Print函数,传参第一个为Date* this,(由const Date* d3->Date* this 显然求安县被放大)为了防止权限被放大我们要在该函数后边+const void Print() const{}

取地址运算符的重载
Date* operator&(){
return this; //this就是实例化对象地址
return nullptr; //可以保护自己程序地址
}
const Date* operator&()const {
return this;
}

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date {
public:Date* operator&() {//return nullptr;return (Date*)0x211;}const Date* operator&() const{return nullptr;}
};
int main() {Date d1;cout <<&d1<< endl;return 0;
}

类和对象下

1.再探构造函数

初始化列表(初始化变量的地方)

引:在初始化列表不管显示写成员变量还是不写 成员变量都会走初始化列表。

1.简单理解:类似于构造函数对变量进行初始化,但是,初始化列表对变量进行初始化时并不是在函数体内进行的,而是在构造函数外边进行初始化,初始化格式以:(冒号)开始,,(逗号)分割的形式,而且每个初始化变量的后边都要加一个括号。

eg:
Date (int year,int mouth,int day)
:_year(year)
,_mouth(mouth)
,_day(day)
{}

 

2.c++规定:a. 初始化列表是类中每个成员变量定义的地方

3.只能在初始化列表进行初始化不能再函数体内进行初始化的类型

a.由const修饰的成员变量只能在初始化列表进行初始化

b.引用类型的成员变量必须在初始化列表进行初始化

c.对于自定义类型如果该自定义变量有对应的默认构造(原本类里边),那么可以不在初始化列表对它进行初始化,如果没有该变量的默认构造,则需要在初始化列表进行初始化,若存在默认构造且在初始化列表对该变量也有进行初始化,则优先使用初始化列表的初始化。

3.初始化列表的缺省值

初始化列表的初始值是在,成员变量定义的地方进行赋值(虽然该法地方进行赋值,但是地方仍然是变量声明的地方并没有开空间)

总结:

 

2.类型转换

对于类型转换,一个类型转换成另一个类型,其实就是把该类型转换成一个临时变量,再把临时变量复制给转换类型。

如果不想类型转换在构造函数前面加关键字explicit

3.static静态成员

特性:

1.静态成员变量必须在类外面进行初始化。

2.静态成员变量不属于类对象(存放在静态区),不存在类对象中,但被所有类所共享。

3.静态成员函数:我们无法正常访问静态成员变量,因为他是私有保护,要i选哪个访问静态成员变量只有用静态成员函数。

静态成员函数没有this指针,只能访问静态成员变量,不能访问其他成员变量。非静态访问静态随便访问。

static int GetCount(){
return count;
}
//调用方法
cout<<A::GetCount<<endl;

4.友元函数

作用:突破类域的访问限定符

1.要想访问私有成员变量则只需在该函数头部加friend 放在类中(只是一种声明,并不是成员函数)

2.友元类:: friend class B 为了访问私有成员变量。

3.友元类特性:单向的,不能交换,不能传递

注意:友元破坏了c++封装特性,不建议多用。

5.内部类

定义:一个类定义在另一个类的里边

1.内部类跟定义的全局类类似,只不过受类类域的限制,并不包含于外部类(计算大小时并不计算内部类)。

2.默认内部类是是外部类的友元(可以直接访问外部类的成员变量)。

6.匿名对象

方便理解:匿名对象就为了我们方便。

注:1.生命周期只在当前这一行。

A aa;//有名对象
A();
A(1);//匿名对象


http://www.ppmy.cn/ops/150245.html

相关文章

C# 多线程 线程池以及异步APM EAP

线程池 是 clr 管理&#xff0c;每个clr 一个线程池实例 最初 是为了 管理线程创建销毁资源 预先在池子里有一些线程 然后 从里面拿取空闲的线程进行逻辑&#xff0c;用途是用来 执行时间短的一些操作 能够在有限的线程中进行复用 好节省资源&#xff0c;就是 时间换空间 以稍微…

leetcode 面试经典 150 题:存在重复元素 II

链接存在重复元素 II题序号219题型数组解法1. 哈希表、2. 滑动窗口难度简单熟练度✅✅✅✅ 题目 给你一个整数数组 nums 和一个整数 k &#xff0c;判断数组中是否存在两个 不同的索引 i 和 j &#xff0c; 满足 nums[i] nums[j] 且 abs(i - j) < k 。如果存在&#xff0…

Django自带admin管理系统使用

1、admin路径地址 localhost:8000/admin 2、使用命令行创建超级管理员 python manage.py createsuperuser 之后按照提示一步一步往下走就好了。 3、修改管理员密码 python manage.py changepassword admin admin是超级管理员的账号 4、后台管理系统注册模型&#xff0c;…

redis缓存篇知识点总结

1.缓存雪崩 当大量缓存数据在同一时间过期(失效)或者 Redis 故障宕机时,如果此时有大量的用户请求,都无法在 Redis 中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃 发生缓存雪崩有两…

2025年,华为认证HCIA、HCIP、HCIE 该如何选择?

眼看都到 2025 年啦&#xff0c;华为认证还吃香不&#xff1f; 把这问题摆在每个网络工程师跟前&#xff0c;答案可没那么容易说清楚。 到底考不考它值当不值当&#xff0c;重点在于您自己的职业规划&#xff0c;还有对行业走向的领会。 2025 年华为认证仍然值得一考&#…

Kotlin 快速上手指南:从安装 IntelliJ IDEA 到编写第一个程序

文章目录 什么是kotlinIntelliJ IDEA安装 IntelliJ IDEA创建 Kotlin 项目运行 Kotlin 程序更改进入后默认打开上一次项目的设置打开 IntelliJ IDEA进入设置:重新启动 IntelliJ IDEA:快速学习Kotlin变量声明类型推断条件表达式定义函数单表达式函数when 表达式when 语句的基本…

1. npm 常用命令详解

npm 常用命令详解 npm&#xff08;Node Package Manager&#xff09;是 Node.js 的包管理工具&#xff0c;用于安装和管理 Node.js 应用中的依赖库。下面是 npm 的一些常用命令及其详细解释和示例代码。 镜像源 # 查询当前使用的镜像源 npm get registry# 设置为淘宝镜像源 …

进程同步之信号量机制

信号量机制 信号量机制是一种用于进程同步和互斥的基本工具&#xff0c;特别是在并发编程中&#xff0c;广泛用于控制对共享资源的访问&#xff0c;避免数据竞争和死锁等问题。信号量机制由荷兰计算机科学家Edsger Dijkstra在1965年提出&#xff0c;并在操作系统的进程同步中发…