C++学习内容笔记整理

这周初步认识了c++,但是学习中依然有许多不理解的地方,特此整理下笔记

c++创造者 本贾尼 斯特劳斯特鲁普

c与c++的区别
1、c++完全兼容c语言的所有内容
2、支持面向对象的编程思想(抽象、封装、继承、多态)
3、支持运算符、函数重载
4、支持泛型编程、模板
5、支持异常处理
6、类型检查严格

1、文件扩展名:.cpp .cc .C .cxx
2、编译器: g++ 大多数需要额外安装
	sudo apt-get install g++
3、头文件 #include <iostream>
	#include <stdio.h>可以继续使用
	#include <cstdio> 建议这样使用
4、输入输出
	<<endl换行
	cout<< 标准输出
	cin>> 标准输入(不需要取地址,c++中有引用)
	cout/cin能自动识别数据类型,不需要占位符
	printf/scanf可以继续使用
5、增加了名字空间
	using namespace std;

名字空间

名字空间:标识符的命名范围,把原本的全局空间进行拆分使用,形成
namespace 空间名{
	//	定义变量
	//	定义函数
	//	设置新类型
}
注意:命令空间可以重名,同名的会自动合并
如何使用命名空间
	直接使用
		空间名::标识符,使用麻烦但是安全
	导入后使用
		using namespace 空间名;使用方便但依然有命名冲突的风险
匿名名字空间
	也就是默认的全部空间,匿名空间中的标识符可以通过, ::标识符 访问,因此也就可能访问被屏蔽的全局的标识符
名字空间中可以嵌套
	也就是名字空间中在定义名字空间,叫嵌套
	不同层次的空间中可以重名,内层自动屏蔽外层的标志
	在访问多层名字空间是需要逐层分解
	n1::n2::n3::num;
名字空间取别名:
	多层空间使用比较麻烦,取别名可以简化该过程
	namespace n123 = n1::n2::n3;

c与c++数据类型的区别
1、c++的结构
不再需要 typedef, 在定义结构变量时,可以省略struct关键字
成员可以是函数,在成员函数中可以直接访问结构成员,不再需要.或->,但必须通过结构变量或结构指针才能调用成员函数
有一些隐藏的成员函数(构造、析构、拷贝构造、复制构造)
可以被继承,可以设置成员的访问权限(面向对象)

2、c++的联合	
	不再需要 typedef, 可以省略 union 关键字
	成员可以是函数	,在成员函数中可以直接访问结构成员,不再需要.或->,但必须通过结构变量或结构指针才能调用成员函数
	有隐藏的成员函数	

3、c++枚举
	不再需要 typedef,可以省略enum关键字
	使用方法与c语言一致,但类型检查更严格,数据不能给枚举变量赋值
	
4、c++布尔类型
	c++中有真正的布尔类型bool是c++中的关键字
	在c++中true、false是关键字,而在c中是宏(用0或1替换)
	true、false在c++中占一个字节,而在c中占4个字节
	
5、c++中的void*
	在c语言中void*可以与任何类型的变量自动转换(万能指针)
	c++中void*类型的指针不能给其他类型的的指针变量赋值
		void* p;
		int* p1 = p;//error
		p = p1;//ok
	c++为什么修改void* p
		为了更安全,c++的类型检查严格
		c++可以自动识别数据类型(函数重载\模板),对于万能指针的需求不再强烈

6、c++中的字符串
	c++中字符串被封装成了string类,也可以与c语言中的字符串进行转换
		(c_str成员函数)
	需要包含string头文件,但已经包含在iostream头文件中
	常见的字符串操作不再需要函数,可以直接使用运算符
		=	strcpy
		==、!=、<=、>=	strcmp
		+=	strcat
		size成员函数 strlen
		sprintf/scanf c++中没有

c++的内存管理

new/delete 分配/释放堆内存的运行符
	功能相当于c语言中的malloc/free
	new 类型;会自动计算字节数,然后从堆中分配相应的内存,然后返回一个带类型的指针
	delete 指针;//释放内存
	new/delete会自动调用类型中的构造函数和析构函数
	注意:不能与c语言中的malloc/free混用,在c++中不建议使用malloc/free
new[]/delete[]
	new 类型[n];用于为数组分配内存,n是数组长度,会调用n次析构函数
	delete[]指针;专门释放数组内存,会调用n此析构函数,如果错用delete后果是不确定的
	new[] 所申请的内存的前4个字节,存储着数组的长度(仅限自定义类型)
new/delete可能产生的错误	
	注意:new/new[]分配内存失败时不会返回NULL指针,而是跑出异常bad_alloc,如果不处理程序就会结束
	delete/delete[] 不能重复释放
	delete/delete[] 释放野指针后果不确定,但释放空指针是安全的(释放前先判断)

malloc/free与new/delete的区别
			new/delete	malloc/free 不同点
	身份: 	运算符		函数
	参数: 	类型		字节数
	返回值:	带类型的地址	void*
	析构/构造自动调用	不调用
	错误:	抛异常		返回空指针
	
	相同点:
		都能管理堆内存
		不能重复释放
		可以释放空指针	

c++中的函数

函数重载
	什么是函数重载
		在c++中,只要函数的参数列表不同,函数名可以相同,这些同名函数构成重载关系
	函数重载的机制
		c++代码在编译时函数的参数类型会添加的函数名中,最终生成的函数名并不相同	
	注意:由于c代码在gcc编译时不会经历换名,因此c++代码不[直接调用]c编译器编译出的目标文件、库文件
		extern "C" {} 
	重载和作用域
		同一作用域下的同名函数才构成重载关系,不同作用域(父子)下的同名函数构成隐藏关系
	重载的解析过程
		当调用函数时,编译器会根据实参和形参的类型的匹配情况没选择一个确定的重载版本,这个过程就叫重载解析
		实参和形参的匹配情况有三种:
			1 找到最佳的匹配函数,直接生成调用代码
			2 找不到匹配函数,编译器给出错误信息
			3 找不到匹配函数,实参经过类型提升,可以找到一个比较合适的,编译器
		编译器找到多个匹配的函数,但没有最佳的,此时会产生二义性错误,这种错误解决方案是调整实参类型
	确定重载函数的步骤
		1 候选函数
		函数调用的第一步就是确定所有的同名函数
		2 选择可行性函数
		从候选函数中选择一个或多个函数,选择的标准是参数的个数和类型
		3 寻找最佳匹配方案
		优先选择完美的匹配方案,其次个数完全匹配,其次内存字节数
	const会影响重载
		参数是指针、引用类型是否用cosnt修饰会影响重载结果
	重载的优缺点
		优点:方便使用(不用取多个函数名,不用回调)
		缺点:可能引起编译错误(二义性),代码段会增大
		多态 函数重载也是一种多态,它是在编译期间确定调用了内个版本的函数,这种叫做编译时多态
默认形参
	在c++中可以给函数的参数变量设置默认值,当调用这种函数,如果没有提供实参而使用默认参数
	如果只有一部分参数设置默认形参,那设置默认形参的参数必须连续且靠右
		void func(int n1,int n=100);
	如果函数的声明和定义分开实现,那么只需要在声明时设置默认形参即可
	函数的默认形参是在编译期间确定的,因此默认形参只能设置常量、表达式、全局变量
	默认形参会影响函数重载,提高二义性的概率
	注意:如果函数已经重载,尽量不要设置默认形参

内联函数
	普通函数在编译时生成二进制指令存放在代码段中,调用时是生成调用命令(跳转),然后执行到调用代码位置时跳转到函数所在的代码段中执行
	把函数生成的二进制指令复制到函数的调用位置
	优点:可以提高程序的运行速度(不需要跳转返回),缺点:导致可执行文件增大(空间换时间)
	显示内联和隐式内联
		显示内联:在函数前加inline(c语言c99语法标准也可以使用)关键字
		隐式内联:结构、联合、类中的内部成员函数,这种函数会被编译器优化成内联函数		
	注意:inline对编译器只有建议权,具体是否真正内联由编译器说了算

	内联的机制与宏函数非常相像,具体的区别:
		函数					语句替换
		拷贝函数的二进制指令		展开宏函数代码
		传参					没有参数和返回值
		检查参数类型				不检查参数类型
		有返回值					只有执行结果
		
	内联的适用条件
		由于内联会造成可执行文件的变大,增加内存开销(占用代码段),因此只有一次调用多次执行且简单的函数适合内联
		调用次数少且复杂的函数,内联后不能显著提高速度,不足以抵消牺牲空间带来的损失
		如果函数带有递归特征,则无法实施内联,编译器会忽略inline关键字
	
引用
	什么是引用
		引用就是起别名,声明一个标识符与其他对象进行绑定,相当于一个对象对应多个名字
	什么时候适合使用
		函数传参使用,与指针相比不需要额外空间,也不用赋值,仅仅是内存与标识符的绑定
		应用虽然很好,但不能完全替代指针,如使用堆内存时仍然需要指针配合
	
	使用引用时要注意的问题
		定义引用时必须初始化,不存在空引用,但可能存在悬空引用
			函数返回局部变量的引用,当函数执行完毕后,变量就会被销毁,此时返回的引用就是悬空引用
		一旦引用不能更改目标
			引用一旦完成定义和初始化后,标识符就与普通变量一样,它就代表引用目标,一旦引用终生不能改变目标
		可以引用无名的临时对象,但必须使用常引用(相当于定义一个变量)
		如果引用的目标具备const属性,那么引用也必须带const
		
c++中的指针与引用的相同点和不同
	相同:函数之间共享变量,获取返回值,提高传参效率
	不同点:
		引用					指针
		取名机制				数据类型		
		不需要额外存储空间	需要4~8字节存储地址编号
		不能为空				可以为空	
		映射关系				指向关系
		没有二级引用			有二级指针
		无法与堆内存配合使用	可以配合使用堆内存
		直接访问目标			需要解引用
		可以定义数组引用		可以定义数组指针
		不能定义引用数组		可以定义指针数组

强制类型转换
c语言的强制类型转换在c++中还可以继续使用,但是有安全隐患,建议使用c++的强制转换
静态类型转换
static_cast<目标类型>(源目标);
两种类型至少有一个方向上能做隐式类型转换,否则报错
去常类型转换
const_cast<目标类型>(源类型)
源类型和目标类型只有const和非cosnt的却别,只适用于指针和引用
const int num;
int* p = const_cast<int*>(&num);
重解释类型
reinterpert_cast<目标类型>(源类型)
因为指针本质就是一个整数,任何的整数类型都可以与指针类型进行转换,专用于指针类型与整形转换
动态类型转换
dynamic_cast<目标类型>(源类型)
目标类型和源类型必须是指针或引用,源类型和目标类型之间存在继承关系 源类型继承了目标

操作符别名
and &&
or ||
not !
<% {
%> }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值