栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++学习笔记

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++学习笔记

文章目录

一、基础入门

1、常量2、关键字3、数据类型

3.1、整型3.2、浮点型3.3、字符型3.4、字符串类型3.5、布尔类型 4、数据的输入与输出5、运算符6、数组

6.1、一维数组6.2、二维数组 7、函数8、指针9、结构体 二、核心编程

1、内存分区2、引用3、函数高级4、struct与class的区别5、防止头文件重复包含6、构造函数与析构函数7、深拷贝与浅拷贝8、类的特性9、this指针10、常函数、常对象11、友元12、运算符重载13、继承14、多态15、文件操作 三、提高编程

1、函数模板2、类模板3、STL概述4、string5、vector6、deque7、Stack8、Queue9、list10、set11、map12、函数对象13、算法

一、基础入门 1、常量

宏常量 #define
常量 const

#include<>

// 宏常量
#define DAY 7

int main() {
	// const常量
	const int month = 12;
	return 0;
}

面试题:宏常量与const常量有什么区别?

    const常量有数据类型,在编译阶段进行类型检查,而宏常量没有数据类型,也就不存在类型检查const常量在运行阶段进行替换,而宏常量在预编译阶段进行替换;
2、关键字
asmdoifreturntypedef
autodoubleinlineshorttypeid
booldynamic_castintsignedtypename
breakelselongsizeofunion
caseenummutablestaticunsigned
catchexplicitnamespacestatic_castusing
charexportnewstructvirtual
classexternoperatorswitchvoid
constfalseprivatetemplatevolatile
const_castfloatprotectedthiswchar_t
continueforpublicthrowwhile
defaultfriendregistertrue
deletegotoreinterpret_casttry
3、数据类型

定义各种数据类型是为了给变量分配合适的内存空间,避免造成资源浪费。sizeof(DataType)用于计算数据类型所占内存大小。

3.1、整型
数据类型占用空间取值范围
short2字节(-2^15 ~ 2^15-1)
int4字节(-2^31 ~ 2^31-1)
longWindows为4字节,Linux为4字节(32位),8字节(64位)(-2^31 ~ 2^31-1)
long long8字节(-2^63 ~ 2^63-1)
3.2、浮点型
数据类型占用空间有效数字范围
float4字节7位有效数字
double8字节15~16位有效数字

默认情况下,浮点数的输出只显示6位有效数字

float f = 3.14f; //默认小数位double,加上f表示为float型
double d = 3.14;

// 科学计数法3.14 * 10^-2 = 0.0314
float f2 = 3.14e-2;
3.3、字符型

C和C++中字符型变量char只占用1个字节,字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元。

ASCII码表:

ASCII值控制字符ASCII值字符ASCII值字符ASCII值字符
0NUT32(space)64@96
1SOH33!65A97a
2STX34"66B98b
3ETX35#67C99c
4EOT36$68D100d
5ENQ37%69E101e
6ACK38&70F102f
7BEL39,71G103g
8BS40(72H104h
9HT41)73I105i
10LF42*74J106j
11VT43+75K107k
12FF44,76L108l
13CR45-77M109m
14SO46.78N110n
15SI47/79O111o
16DLE48080P112p
17DCI49181Q113q
18DC250282R114r
19DC351383S115s
20DC452484T116t
21NAK53585U117u
22SYN54686V118v
23TB55787W119w
24CAN56888X120x
25EM57989Y121y
26SUB58:90Z122z
27ESC59;91[123{
28FS60<92/124|
29GS61=93]125}
30RS62>94^126`
31US63?95_127DEL

转义字符:

转义字符含义ASCII码值(十进制)
a警报007
b退格(BS) ,将当前位置移到前一列008
f换页(FF),将当前位置移到下页开头012
n换行(LF) ,将当前位置移到下一行开头010
r回车(CR) ,将当前位置移到本行开头013
t水平制表(HT) (跳到下一个TAB位置)009
v垂直制表(VT)011
\代表一个反斜线字符""092
代表一个单引号(撇号)字符039
"代表一个双引号字符034
?代表一个问号063
数字0000
ddd8进制转义字符,d范围0~73位8进制
xhh16进制转义字符,h范围09,af,A~F3位16进制
3.4、字符串类型
    C风格字符串: char 变量名[] = "字符串值"C++风格字符串: string 变量名 = "字符串值"

注意:C++风格字符串,需要加入头文件#include

#include
#include

using namespace std;
int main() {
	char c1 = 'a';
	// c风格的字符串
	char str[] = "abc";
	// c++风格的字符串 需要头文件#include
	string str2 = "abc";

	cout << "char str[]" << str << endl;
	cout << "string str2" << str2 << endl;
	system("pause");
	return 0;
}
3.5、布尔类型

bool类型只有两个值:true — 真(本质是1),false — 假(本质是0)

bool类型占1个字节大小

对bool类型进行赋值时,只要不为0,则为true

4、数据的输入与输出
#include
#include
using namespace std;

int main() {
	// 对于cin的连续输入,是以空白字符为分隔符的
	// (下一个变量从非空白字符开始)
	int a, b;
	cout << "输入a和b:";
	cin >> a >> b;

	char c, d;
	cout << "输入c和d:";
	cin >> c >> d;

	string e, f;
	cout << "输入e和f:";
	cin >> e >> f;

	cout << "a = " << a << ", b = " << b << endl;
	cout << "c = " << c << ", d = " << d << endl;
	cout << "e = " << e << ", f = " << f << endl;

	// C++中的scanf_s()相当于C语言中的scanf()
	// C++中的printf_s()相当于C语言中的printf()
	// 当需要格式化输入或输出时,可考虑使用scanf_s()和printf_s
	cout << "输入a和b:";
	scanf_s("%d,%d", &a, &b);
	printf_s("a = %d, b = %dn", a, b);

	return 0;
}


对于不确定输入次数的,可通过ctrl + z结束输入

string str;
int index = 0;
// ctrl + Z 结束输入
while (cin >> str) {	
	cout << "index = " << ++index << "str = " << str << endl;
}
5、运算符
运算符术语示例结果
+正号+33
-负号-3-3
+10 + 515
-10 - 55
*10 * 550
/10 / 52
%取模(取余)10 % 31
++前置递增a=2; b=++a;a=3; b=3;
++后置递增a=2; b=a++;a=3; b=2;
前置递减a=2; b=–a;a=1; b=1;
后置递减a=2; b=a–;a=1; b=2;
=赋值a=2; b=3;a=2; b=3;
+=加等于a=0; a+=2;a=2;
-=减等于a=5; a-=3;a=2;
*=乘等于a=2; a*=2;a=4;
/=除等于a=4; a/=2;a=2;
%=模等于a=3; a%2;a=1;
==相等于4 == 30
!=不等于4 != 31
<小于4 < 30
>大于4 > 31
<=小于等于4 <= 30
>=大于等于4 >= 11
!!a如果a为假,则!a为真; 如果a为真,则!a为假。
&&a && b如果a和b都为真,则结果为真,否则为假。
||a || b如果a和b有一个为真,则结果为真,二者都为假时,结果为假。

两个整数相除只保留整数,只有整数可以进行取模运算

int ii1 = 0 % 10; //正确
int ii2 = 10 % 0; //错误
6、数组 6.1、一维数组
    数据类型 数组名[ 数组长度 ];数据类型 数组名[ 数组长度 ] = { 值1,值2 ...};数据类型 数组名[ ] = { 值1,值2 ...};

一维数组名:

    可以统计整个数组在内存中的长度可以获取数组在内存中的首地址数组名是常量,不可以赋值
6.2、二维数组
    数据类型 数组名[ 行数 ][ 列数 ];数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};

二维数组名:

    查看二维数组所占内存空间获取二维数组首地址
7、函数

函数的声明可以多次,函数的定义只能一次
函数的分文件书写:
1)创建.h头文件,写函数声明,及程序需要的文件头
2)创建cpp原文件,写函数的定义
3)cpp引入头文件include “swap.h”

8、指针

在32位系统下,所有数据类型的指针都是占4字节
在64位系统下,所有数据类型的指针都是占8字节
空指针指向的地址为0,且无法访问,访问报错
指针定义时若没有初始化,则初始化为NULL

野指针访问出错

#include
using namespace std;

// 引用传递/地址传递
void swap(int *a, int *b) {
	int temp = *a;
	*a = *b;
	*b = temp;
}

int main() {
	int a = 10;
	int b = 20;
	int *p = &a;
	int *p2 = NULL;

	cout << "a的地址:" << &a << endl;
	cout << "a的值:" << a << endl;
	cout << "指针p:" << p << endl;
	cout << "解引用*p = " << *p << endl;
	cout << "指针类型的大小:" << sizeof(int *) << endl;
	cout << "空指针p2:" << p2 << endl;
	// 空指针指向的地址是0x0000,对空指针解引用运行出错(编译可通过)
	//cout << "空指针p2解引用:" << *p2 << endl;
	
	// 常量指针,指针指向的值不可改
	const int *p3 = &a;
	p3 = &b;
	// 指针常量,指针的指向不可改
	int *const p4 = &a;
	*p4 = 30;
	const int *const p5 = &a;
	
	int arr[] = { 1, 2, 3, 4, 5 };
	int *p6 = arr;
	cout << "利用指针打印int数组:";
	for (int i = 0; i < 5; i++) {
		cout << *p6 << " ";
		// 偏移一个int大小
		p6 ++;
	}

	// 引用传递/地址传递
	cout << "na = " << a << ", b = " << b << endl;
	swap(&a, &b);
	cout << "a = " << a << ", b = " << b << endl;

	system("pause");
	return 0;
}
9、结构体

结构体作为函数参数时,使用结构体指针可以节省内存。

// 使用const可防止误改结构体中的值
void print(const Student *s) {
	cout << s->name << " " << s->age << endl;
}
二、核心编程 1、内存分区


代码区(运行前):共享(一个程序的多个进程共享代码),只读(代码区不可修改)
全局区(运行前):该区域的数据在程序结束后由操作系统释放

栈区(运行后):函数不要返回局部变量的地址

2、引用

1、引用定义时必须初始化,且引用不可修改指向
2、若函数的返回值为引用,则可以作为左值进行赋值操作
3、引用的本质是指针常量int * const ref = &a
4、引用符号写到靠近数据类型的一边,而不是变量名

3、函数高级

1、函数的某个参数有默认值,则其之后的参数也必须有默认值

2、函数的声明与函数的定义的参数只能有一个有默认值

3、

4、函数重载

5、函数有默认值与函数重载可能出现二义性

7、引用作为重载条件

4、struct与class的区别

C++中,struct默认权限为公有,而class默认属性为私有

5、防止头文件重复包含

6、构造函数与析构函数

C++默认提供无参构造函数,拷贝构造函数和无参析构函数。
若自定义了普通构造函数,则不再提供拷贝构造函数;
若自定义了拷贝构造函数,则不再提供任何构造函数。

拷贝构造函数调用的时机:

7、深拷贝与浅拷贝

浅拷贝:对于指针类型,只是将原对象的指针所指的地址值赋给了新对象,浅拷贝存在堆内存重复释放的问题(默认提供的拷贝构造函数就是浅拷贝)
深拷贝:对于指针类型,需要重新new一个堆内存,解决浅拷贝问题,需要自定义拷贝构造函数

8、类的特性

C++会给每个空对象分配1字节的内存空间,是为了区分空对象占内存的位置
当类只有一个非静态成员变量int时,只占4字节
成员变量和成员函数是分开存储的,只有非静态成员变量属于类对象上

9、this指针

this指针的本质是student * const this,指针常量,不可修改指向
1、用于将成员变量与同名的成员函数形参区别开

2、用于成员函数的链式调用

3、类对象的空指针问题

10、常函数、常对象

1、常函数内的this指针是const student * const this
2、常函数中只能修改mutable修改的成员变量
3、常对象只能调用常函数

11、友元

全局函数做友元


12、运算符重载



成员函数重载和全局函数重载运算符的优先级?
不可重复定义

运算符重载函数也可发生函数重载
内置的数据类型不可以发生运算符重载



前置递增返回引用,后置递增返回值


对于带有指针变量的类,编译器自带的赋值运算符是浅拷贝,会出现堆内存重复释放的问题(同拷贝函数)

#include
#include
using namespace std;

class Person {

public:
	int age;
	int num;
	int *tt;
	Person(int age, int num):age(age),num(num){
		this->tt = new int(10);
	}
	
	Person(const Person &p) {
		cout << "拷贝构造函数" << endl;
		this->age = p.age;
		this->num = p.num;
		// 对于有指针成员变量的类,需要重写赋值运算符和拷贝构造函数改为深拷贝
		this->tt = new int(*p.tt);
	}
	

	~Person() {
		if (this->tt != NULL) {
			delete this->tt;
			this->tt = NULL;
		}
	}

	// 重载运算符+,定义两个Person对象相加的意义
	Person operator-(Person &p) {
		Person temp(this->age - p.age, this->num - p.num);
		return temp;
	}

	// 运算符重载,定义加一个int型变量进行的操作
	Person operator+(int a) {
		Person temp(this->age + a, this->num + a);
		return temp;
	}

	// 重载运算符--, 定义 --p
	Person& operator--() {
		this->num --;
		return *this;
	}

	// 重载运算符--, 定义 p--, 占位参数int表示是后置操作
	Person operator--(int) {
		Person temp = *this;
		this->num--;
		return temp;
	}
	
	// 重载运算符=,定义 this = p,编译器默认提供浅拷贝
	Person& operator=(const Person &p) {
		cout << "赋值运算符" << endl;
		this->age = p.age;
		this->num = p.num;
		// 对于有指针成员变量的类,需要重写赋值运算符和拷贝构造函数改为深拷贝
		this->tt = new int(*p.tt);
		return *this;
	}

};

Person operator+(Person &p1, Person &p2) {
	Person temp(p1.age + p2.age, p1.num + p2.num);
	return temp;
}

// 重载运算符<<,定义 cout << p;,只能通过全局函数重载,无法通过成员函数重载
ostream& operator<<(ostream &cout, Person &p) {
	cout << "age = " << p.age << " num = " << p.num;
	// cout进行链式调用,需要返回ostream的引用
	return cout;
}

// 重载运算符++,定义 ++p
// 前置操作返回的是引用
Person& operator++(Person &p) {
	p.num ++;
	return p;
}

// 重载运算符++,定义 p++, 多一个int占位参数,表示是后置操作
// 后置操作返回的是值
Person operator++(Person &p, int) {
	Person temp = p;
	p.num++;
	return temp;
}


int main() {
	Person p1(21, 1);
	Person p2(20, 2);

	Person p3 = p2 + p1;
	cout << "p3: age = " << p3.age << " num = " << p3.num << endl;

	Person p4 = p1 - p2;
	cout << "p4: age = " << p4.age << " num = " << p4.num << endl;

	Person p5 = p1 + 2;
	cout << "p5: age = " << p5.age << " num = " << p5.num << endl;

	cout << p5 << endl;


	++(++p5);

	p5++;

	cout << p5 << endl;

	--(--p5);

	p5--;

	cout << p5 << endl;
	

	Person p6(0, 0);
	p6 = p5;
	cout << "p6: " << p6 << endl;

	return 0;
}
13、继承


父类中所有的非静态成员都会被子类继承下去,虽然父类的私有成员在子类中访问不到。

继承中,父类先构造后析构,子类后构造先析构
父类和子类中存在同名成员变量/函数,直接访问的是子类的成员变量/函数,访问父类中的同名成员变量/函数需要加作用域,静态成员同理。

Son s;
s.Father::m_a; 
s.Father::func();

如何子类中存在与父类同名的成员函数,则父类中所有的同名成员函数都会被隐藏,尽管父类中的同名成员函数与子类中的同名成员函数是重载关系,所以访问父类中的同名成员函数需要加作用域



14、多态

父类中的函数需要加virtual关键字,加上virtual后,虚函数变成了一个虚函数指针vfptr,指向了一个虚函数表,虚函数表内记录了虚函数的地址

多态实现计算器

#include
#include
using namespace std;

class AbstractCalculator {
public:
	int a;
	int b;
	virtual int calculate() {
		return 0;
	}
};

class AddCalculator : public AbstractCalculator {
	int calculate() {
		return a + b;
	}
};

class SubCalculator : public AbstractCalculator {
	int calculate() {
		return a - b;
	}
};

int main() {

	AbstractCalculator *ptr = new AddCalculator;
	ptr->a = 10;
	ptr->b = 10;
	cout << ptr->a << " + " << ptr->b << " = " << ptr->calculate() << endl;

	delete ptr;
	ptr = new SubCalculator;
	ptr->a = 11;
	ptr->b = 10;
	cout << ptr->a << " - " << ptr->b << " = " << ptr->calculate() << endl;
	delete ptr;
	return 0;
}

纯虚函数

// 纯虚函数,包含纯虚函数的类称为抽象类,无法实例化
// 若其子类没有重写该纯虚函数,否则也是抽象类,无法实例化
virtual int calculate() = 0;


父类的析构函数需要加virtual关键字,虚析构函数;纯虚析构需要有声明,也需要有实现

15、文件操作


#include
#include
#include
using namespace std;


class Person {
public:
	char name[64];
	int age;
};


int main() {
	
	

	

	// 二进制文件
	ofstream ofs("person.txt", ios::out | ios::binary);
	Person p = { "张三" , 18 };
	ofs.write((const char *)&p, sizeof(Person));
	ofs.close();


	ifstream ifs("person.txt", ios::in | ios::binary);
	if (!ifs.is_open()) {
		cout << "Fail to open file!" << endl;
	} else {
		Person ptr;
		ifs.read((char *)&ptr, sizeof(Person));
		cout << "name = " << ptr.name << " age = " << ptr.age << endl;
	}
	ifs.close();
	return 0;
}
三、提高编程 1、函数模板

1、模板函基本格式

// 模板函数add
template
T add(T a, T b) {
	return a + b;
}

// 普通函数add
int add(int a, int b) {
	return a + b;
}


template
void swapElem(T &a, T &b) {
	T temp = a;
	a = b;
	b = temp;
}

template
void swapData(T *a, T *b) {
	T *temp = *a;
	*a = *b;
	*b = *temp;
}

2、函数模板的自动类型推到不会发生强制类型转换,而指定类型会发生强制类型转换

3、当模板函数的参数为引用或指针类型时,不会发生强制类型转换

4、当模板函数和普通函数同时满足函数调用时,优先调用普通函数,若想强制调用模板函数,空参数模板会强制调用模板函数

add(a, b); // 调用的是普通函数
add<>(a, b); // 空参数模板强制调用的是函数模板

5、函数模板对于自定义类型可能并不兼容,可使用模板具体化版本来解决自定义类型问题

template
bool comparator(T a, T b) {
	if (a == b) {
		return true;
	}
	return false;
}

// 利用模板函数具体化解决自定义类型问题
template<> bool comparator(Person p1, Person p2) {
	if (p1.name == p2.name && p1.age == p2.age) {
		return true;
	}
	return false;
}
2、类模板

1、类模板基本格式

// 全局函数的类外实现
// 1.先声明class
template
class Person;

// 2.写函数实现
friend void printPerson(Person p) {
	cout << "name :" << p.name << " age:" << p.age << endl;
}


// 类模板可以有默认类型
// 类模板中的成员函数在调用时才会创建
template
class Person {

	// 全局函数的类内实现
	friend void printPerson<>(Person p) {
	cout << "name :" << p.name << " age:" << p.age << endl;
}

	// 全局函数类外实现,注意需要加空参数列表
	//(这是一个普通函数,而不是函数模板,需要加空参数列表)
	friend void printPerson2<>(Person p);

public:
	NameType name;
	AgeType age;

	Person(NameType name, AgeType age) : name(name), age(age) {}

	void showInfo() {
		cout << "name :" << name << " age:" << age << endl;
	}
	
	// 类外实现
	void setName(NameType name);
};

// 类模板成员函数类外实现
template
void Person::setName(NameType name) {
	this->name = name;
}

2、模板类作为父类的两种实现方式

// 子类在继承类模板时,需要指定父类中的泛型
class Boss : public Person {

};

// 子类想灵活指定父类的类型,也需要进行模板化
template
class Employee : public Person {
	T3 t;
};

3、模板类分文件的两种实现方式
(1)使用时引用.cpp文件而不是.h文件,类模板的成员函数一开始并不会创建,只包含.h文件会链接失败,直接包含cpp,则编译器可以正确链接
(2)将.cpp和.h写到一个文件,文件后缀名改为.hpp

3、STL概述

1、STL六大组件:容器、算法、迭代器、仿函数、适配器、空间配置器
2、两种常用的遍历方式
3、位置参数都是迭代器

// 遍历方式1
for (vector::iterator it = v.begin(); it != v.end(); it++) {
	cout << *it << " ";
}
cout << endl;

// 遍历方式2 需要包含#include
for_each(v.begin(), v.end(), func);
cout << endl;
4、string

1、string本质上是一个类,类里面维护着一个char *变量
2、构造函数

3、string的赋值

4、string的拼接

5、string的查找与替换

6、字符串的比较

7、字符串的存取

8、字符串的插入与删除

9、字符串的截取

5、vector

1、基本概念
vector本质上是一个类,类中维护一个单端数组,进行扩展时,是申请更大的空间,并将旧数据拷贝到新数组中,其迭代器是支持随机访问的(数组连续存储的特性)。

2、构造函数

3、vector的赋值

4、vector对容量的操作

5、vector的插入与删除

6、vector中的数据存取

7、两个容器元素的互换

用swap可收缩空间

8、预留空间
减少vector扩容的次数,vector的每次动态扩展都需要申请一片更大的空间并复制旧数据。

6、deque

1、基本概念
deque本质上是一个类,类中维护一个双端数组,相对而言,对头部的插入删除操作的速度比vector快,但vector访问元素时速度比deque快,其迭代器是支持随机访问的(数组连续存储的特性,虽然分为多个数组存储)。
只读迭代器const_iterator



2、构造函数

3、deque的赋值操作

4、插入与删除

5、数据存取

6、排序

7、Stack

1、基本概念
栈中只有栈顶元素才允许被访问,不可以遍历栈中元素

2、基本操作

8、Queue

1、基本概念
只可访问队头与队尾,不支持遍历行为

2、基本操作

9、list

1、基本概念
链式存储,本质上是一个双向循环链表,其迭代器是双向迭代器,不支持随机访问

2、构造函数

3、赋值与交换

4、大小操作

5、插入与删除

6、数据存取

7、反转与排序

class Person {
public:
	int age;
	int height;

	Person(int age, int height):age(age),height(height) {}
};

// 自定义类型Person比较器,先按年龄升序,再按身高降序
bool PersonCompartor(Person& p1, Person& p2) {
	if (p1.age == p2.age) {
		return p1.height > p2.height;
	} else {
		return p1.age < p2.age;
	}
}

int main() {
	list L;
	Person p1(10, 150);
	Person p2(40, 170);
	Person p3(10, 140);
	Person p4(30, 180);
	Person p5(10, 160);
	Person p6(10, 135);
	
	L.push_back(p1);
	L.push_back(p2);
	L.push_back(p3);
	L.push_back(p4);
	L.push_back(p5);
	L.push_back(p6);
	
	// 自定义类型无法直接排序,需要传入比较器
	L.sort(PersonCompartor);
	
	for (list::iterator it = L.begin(); it != L.end(); it++) {
		cout << "age: " << it->age << " height: " << it->height << endl;
	}
	return 0;
}
10、set

1、基本概念
所有元素在插入时会被自动排序,set/multiset属于关联式容器,底层用二叉树实现,set不可以有重复的元素,在插入时会自动去重,而multiset可以有重复的元素

2、构造与赋值

3、大小与交换

不支持resize操作

4、插入与删除

5、查找与统计

对于set而言,count()只可能为0或1

6、set与multiset的区别
set不可以有重复数据,而multiset可以;
set插入数据的同时返回插入结果,表示插入是否成功,而multiset不会做检测

7、对组pair

8、改变set内置类型的排序规则(仿函数)

11、map

1、基本概念
map中所有元素都是pair,pair中第一个值为key(键值),第二个为value(实值),所有元素会根据键值自动排序,也是关联式容器,底层采用二叉树实现,multimap允许存在键值重复的元素

2、构造与赋值

3、大小与交换

4、插入与删除

5、查找与统计

12、函数对象

重载了函数调用操作符()的类,其对象称为函数对象,仿函数是一个类,而不是一个函数

13、算法



























转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/703249.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号