C++杂项(供个人复习用,也可以来凑凑热闹的~)

本文详细介绍了C++的历史、标准库,包括函数库和面向对象类库,探讨了namespace与class的区别,深入讲解了C++中的引用、const、函数参数默认值、内存分区、构造函数、拷贝构造函数、移动构造函数、赋值函数、this指针、继承和多态等概念。此外,还涵盖了STL的六大组件、常函数、lambda表达式、多线程以及智能指针的应用。
摘要由CSDN通过智能技术生成

C++历史

美国新泽西州贝尔实验室Bell Lab

由C++之父Bjarne Stroustrup(丹麦)发明

C++标准库

标准函数库

​ 输入/输出 I/O

​ 字符串和字符处理

​ 数学

​ 时间、日期和本地化

​ 动态分配

​ 宽字符函数

面向对象类库

​ 标准的 C++ I/O 类

​ String 类

​ 数值类

​ STL 容器类

​ STL 算法

​ STL 函数对象

​ STL 迭代器

​ STL 分配器

​ 本地化库

​ 异常处理类

​ 杂项支持库

namespace与class的区别

namespace主要是为了防止多个开发人员开发时命名重合。

namespace可以被再次打开并添加新成员。但class不允许。

C++引用

1.引用必须被初始化,指针不必

2.引用初始化后不能被改变,指针可以改变所指的对象

3.不存在指向空置的引用,存在指向空值的指针

引用的功能指针都能实现,不过指针不安全,写的时候一不注意就是BUG,用引用相对安全。

const

const int x=3; 将x变成常量,值为3;后续无法对x赋值,否则报错。

常量指针(const int * p、int const * p) --------*p为常量

指针常量(int * const p) ----------p为常量

函数参数默认值

例:void fun(int i,int j=5,int k=10); 有默认参数值的参数必须在参数表的最右端

内联函数inline

在调用时通过将函数体直接插入调用处来实现的,这样可以大大减少由函数调用带来的开销(特别是循环)

内存分区

栈区

int x=0; int* p=nullptr;

堆区

int* p=new int[20];

全局区(或者叫静态区)

全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域

常量区

string str =“hello”;

注意const a=10; 在函数内a放在栈区,这种写法主要是为了防止程序员在后续的代码中误操作a变量而添加的一个约束条件,并不会影响它存放的位置

代码区

用于存储程序编译连接后生成的二进制机器码指令的内存区域。该部分内容可通过反汇编操作将机器码转换为汇编语言。

构造函数

有参数时 Teacher t1(10);

巧用this指针时this会放前 Teacher(this,10);

拷贝构造函数

  1. 当用类的一个对象去初始化该类的另一个对象(或引用)时系统自动调用拷贝构造函数实现拷贝赋值。
  2. 若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数。
  3. 当函数的返回值是类对象时,系统自动调用拷贝构造函数。

​ Teacher::Teacher(const Teacher &tea){};

移动构造函数

专门处理这种用a初始化b后就将a析构的情况

避免了新的空间的分配,大大降低了构造的成本

Teacher::Teacher(Teacher && moveFrom){};

赋值函数

Teacher& operator = (const Teacher &tea)	//const是不希望通过引用改原数据;一般不写出tea

​	{	if(this!=&t)	{	data=tea.data;	}	//避免自己给自己赋值

​		return *this;

​	}

移动赋值函数

Teacher& operator = (Teacher && moveFrom){}

this指针

Teacher t1; 则this 等价于 &t1

成员函数使用和成员变量同名的参数时,有this->的是成员变量

公有继承

public变public

protected变protected

private变无法访问

保护继承

public变protected

protected变protected

private变无法访问

私有继承(C++默认)

public变private

protected变private

private变无法访问

is a

只能用派生类初始化基类,不能反过来,然后派生类中基类没有的数据成员会被截断

基类指针指向派生类时也会截断派生类中基类没有的数据成员

虚继承

菱形继承时会导致 最基类 空间冗余

​	class 工人 : virtual public 人{};

​	class 农民 : virtual public 人{};

​	class 农民工 : public 工人 , public 农民{};

友元函数友元类

类的友元函数是定义在类外部,但有权访问类的所有private成员和protected成员。

友元类的整个类及其所有成员都是友元。

成员函数重载的第一个参数为this指针(经常不写出)

输出运算符<<重载由于要求第一个参数必须为 ostream &a,所以不能使用成员函数重载,而使用友元函数重载。

静态的没有

虚函数

1.定义派生类对象,并调用对象中未被派生类没有的基类函数A。同时在该函数A中,又调用了已被派生类覆盖的基类函数B,那此时将会调用基类中的函数B;如果该函数是虚函数(基类的函数加virtual),则会调用派生类中的该函数。

2.在使用指向派生类对象的基类指针,并调用派生类中的覆盖函数(p->fun())时,如果该函数不是虚函数,那么将调用基类中的该函数;如果该函数是虚函数(基类的函数加virtual),则会调用派生类中的该函数。

tips:基类指针指向派生类才有多态性的展现

基类的同名函数加了virtual后,派生类的同名函数加不加virtual都一样的,加了可以增强可读性

placement new

char* buf = new char[sizeof(A) * 3];//申请了3个A的内存

A* pc = new(buf)A();//运用申请好的buf的内存,在buf上赋值

虚析构函数

基类中析构函数加virtual,delete基类指针时会连同删除掉派生类所有在堆中申请的内存

基*p=new 派生(); delete p; p=nullptr; //不怕内存泄露

基类的析构函数一定要加 virtual !!!!

虚函数表

类实例化后会产生一个虚函数表指针,指向虚函数表,虚函数表放着虚函数的指针

若派生类覆盖基类,则虚函数表内的虚函数指针就不指向基类的虚函数了

重载

同类内,同名,不同参

覆盖

分别在基类派生类,同名,同参,加virtual

隐藏(注:基类指针指向new的派生类对象时调用的是基类的函数)

分别在基类派生类,同名,同参时无virtual,不同参时有无virtual皆可

纯虚函数抽象类接口类

virtual int fun()=0; //纯虚函数

含有纯虚函数的类为抽象类,无法实例化对象

抽象类的派生类需要实现所有基类的纯虚函数,才能实例化对象

全为纯虚函数,无成员函数的类,叫接口类

STL(Standard Template Library)标准模板库

6大组件

Container(容器)

​ 顺序容器vector、list链表、deque双队列

​ 关联容器

​ map映射:

​			map<int,string>m;`

​			pair<int,string>p(10,"guangzhou");

​			m.insert(p);

​			cout<<m[10]<<endl;

​ 输出得guangzhou

​ set集合:暂无

Iterator(迭代器)

​ 输入迭代器 读,不能写,只支持自增

​ 输出迭代器 写,不能读,只支持自增

​ 前向迭代器 读和写,只支持自增

​ 双向迭代器 读和写,支持自增和自减

​ 随机访问迭代器 都和写,支持完整的迭代器算术运算;

​ 迭代器是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址

int main(){

vector vec1;	vec1.push_back("hello");

vector<string>::iterator citer1=vec1.begin();

for(;citer!=vec.end();citer1++)	{	cout<<*citer1<<endl;	}

}

Adapter(适配器)

​ 不改变原有接口下,转换成我们期待的接口

​ stack栈、queue单队列、priority_queue优先队列

Algorithm(算法)

​ 只读算法(查找、搜索、统计)

​ 可变序列算法(复制,变换,替换,填充,移除和随机生成等)

​ 排序算法

​ 关系算法(求最值)

​ 堆算法(堆排序)

​ 其他是一些容器特有的算法

Function object(函数对象)

Allocator(分配器)

​ 分配器就用于处理容器对内存的分配与释放请求

常函数

void fun() const {}

1.可以使用数据成员,不能进行修改,对函数的功能有更明确的限定;

2.常对象只能调用常函数,不能调用普通函数;

3.常函数的this指针是const CStu*

lambda表达式

int main()
{
  int a = 10;
   int b = 20;
auto func = [=](type i)->int {
    switch (i)
    {
        case add:	return a + b;
        case sub:	return a - b;
        case mul:	return a * b;
        case divi:	return a / b;
    }
};
cout<<func(add)<<endl;
}

Functional Programming函数式编程

相对面向对象编程的另外一种看待事物的方式,建议知乎搜索下看看哦

std::bind

用法一:

减少调用参数

​	auto fun = [](int *array, int n,int num){}

​	auto newfun = bind(fun, _1, _2, 5);

​ 则newfun()仅需传入2个参数,第三个参数固定为int 5

用法二:

更改参数调用顺序

多线程

创建

	#include <pthread.h>
​	pthread_create (thread指针, attr属性, start_routine运行起始地址, arg运行函数的参数)

终止

​	#include <pthread.h>
​	pthread_exit (status)

智能指针

auto_ptr

unique_ptr

shared_ptr

weak_ptr

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值