C++语法难点
virtual
- 实现类的多态性;基类定义虚函数,子类可以重写该函数;如果使用了virtual关键字,程序将根据引用或指针指向的 对象类型 来选择方法,否则使用引用类型或指针类型来选择方法
- 实现虚继承,避免菱形继承中,重复字段导致的资源浪费
- virtual 函数在地址绑定时是进行晚绑定的,而普通函数是进行早绑定。
C/C++编译:
gcc name.cpp -lstdc++ -o object_name
g++ name.cpp -o object_name#GUN编译器,在windows环境下,生成exe可执行程序。在unix环境下,生成无后缀的可执行文件
通常,在一个C++程序中,只包含头文件和源文件,C++支持对不同源文件进行分别编译,最后对编译好的目标文件做一次链接。头文件中只应该包含声明,类定义,const对象和inline函数【头文件包含在多个源文件中,同时,定义只能出现一次,而申明可以重复多次】
每个C++程序必须有且仅有一个main函数,返回值必须是int型
编译过程中,会检查程序的语法错误、类型错误等。
避免头文件的重复包含
#ifndef SALE
#define SALE
//definition
#endif
指针
野指针:指向非法内存空间的指(没有对应读取权限)
const int * p//常量指针,本质是指针,指针指向的值不可以改,但是指针指向可以修改
int * const p//指针常量,本质是常量,指向不可以修改,指向的值可以修改
const int * const p//指针的指向和指针指向的值都不可以修改
vector
vector 常被称为向量容器,因为该容器擅长在尾部插入或删除元素,在常量时间内就可以完成,时间复杂度为O(1)
;而对于在容器头部或者中部插入或删除元素,则花费时间要长一些(移动元素需要耗费时间),时间复杂度为线性阶O(n)
vector支持动态扩展,且迭代器支持随机访问。
vector<int> vec;
vec.empty()//判断容器是否为空
vec.capacity()//返回容器容量
vec.size()//返回元素个数,容量永远大于元素个数
vec.resize()//重新指定元素个数,超出的被删掉,不够的用零补充
vec.push_back(ele);
vec.pop_back(ele);
vec.insert(iterator,ele);
vec.erase(iterator);
vec.clear();
内存分区
代码区:存放函数体的二进制代码,由操作系统进行管理。存放CPU执行的机器指令,共享且只读,程序运行前存在。
全局区:存放全局变量、常量【main函数外】、静态变量【static】、字符串常量,程序运行前存在。
栈区:由编译器自动分配释放,存放函数的参数值,局部变量、常量【常量由const修饰】等,在函数执行完后自动释放。
堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收。
int * p = new int(10)
int * arr = new int[10]//在堆区创建一个数组
delete[] arr//释放数组的时候需要加上中括号
引用与指针
引用必须要初始化,引用一旦初始化后,就不能再修改了,引用本质上是指针常量,内部通过代码转换实现。
int& ref = ele;//int* const ref = &ele;
ref = 200;//*ref = 200
在函数中,千万不要返回局部变量、局部变量的引用或者指向局部变量的指针。
常量引用:只能用于引用常量,需要用const int& ref = 10;
的形式,引用一块合理的内存空间。
常量const
在全局作用域里定义非const变量,意味着在整个程序中都能访问到。在全局作用域声明的const变量是文件的局部变量,不能被其它文件访问,可以通过指定external
,让其在整个程序中能被访问到。【非const变量默认为external】
被const修饰的对象称为常对象,常对象只能修改被mutable
修饰的变量,同时只能调用常函数。
枚举
enum ele {a,b,c}//第一个枚举成员默认赋值为0,后面每个成员比前面的值大1
可以为一个或者多个枚举成员提供初始值
函数的参数和重载
int func(int a, int b = 20, int c = 30)//默认参数
int func(int a, int)//占位参数
1.如果某个位置已经有了默认参数,那么从左往右都必须有默认参数【默认实参需要在形参列表结尾】。
2.函数声明和实现只能有一个默认参数【不可以重定义默认参数】。
同一个作用域下,函数名相同,但是形参列表不同构成函数重载,函数重载可能和默认参数构成函数的二义性,导致编译报错。
class继承
【默认访问权限是private,而结构体的默认访问权限是public】
public:都可以访问
protected:仅在本类和派生类中可以访问
private:仅在本类中或本类的成员函数可以访问
class 子类:public 父类(, public 父类){//公共继承
}
公有继承:无法访问私有内容,保护权限下的属性仍然为保护权限,私有权限下的属性仍然为私有
保护继承:无法访问私有内容,剩下所有属性都变成保护权限
私有继承:无法访问私有内容,剩下所有属性都变成私有权限
多态
子类重写父类的虚函数,在父类引用指向子类时实现函数地址的晚绑定,
1.定义子类时,先调用父类构造函数,再调用子类构造函数,析构时则先调用子类,再调用父类
2.子类中定义的同名内容将覆盖父类中所有同名内容【例如子类定义的同名函数将覆盖掉父类中所有的同名函数,包括父类中重载的部分】,可以通过子类.父类::父类同名内容
的方式访问父类被覆盖的变量
3.当多继承中,多个父类出现了同名的内容,也需要加上作用域访问
获取类的分布图
#利用编译器打印类的分布图
cl /dl reportSingleClassLayout类名称 文件名称
构造函数
创建一个类,编译器会为每个类添加默认构造函数、析构函数和拷贝构造函数。如果写了构造函数,编译器不再提供构造函数,但是依然提供拷贝构造函数。如果写了拷贝构造函数,编译器不再提供任何构造函数。
className(para){}//构造函数
className(const ClassName &P){}//拷贝构造函数
~className(){}
//括号法调用构造函数
ClassName a;//调用默认构造函数,不要加小括号,ClassName a()会被误解为函数的声明
ClassName a(para);
//显示法调用构造函数
ClassName a = ClassName();
ClassName a = ClassName(para);
ClassName(para)//创建匿名对象
构造函数与析构函数没有返回值,也不写void,函数名称与类名相同,析构函数没有参数。
静态成员函数
所有对象共享静态成员函数和静态成员变量,静态成员函数只能访问静态成员变量
ClassName c;
c.func();//通过对象访问静态成员函数
ClassName::func();//通过类名直接访问静态成员函数
对象的存储
- C++编译器会为每个空对象分配一个字节空间,是为了区分空对象占内存的位置。
- 非静态变量存储在类对象中,静态成员变量和成员函数不存储在类对象中【只有一份】
this指针【指针常量】
this指针存在于每一个非静态成员函数中,指向被调用的成员函数所属的对象。
*this返回对象本身
ClassName& func(para){
return *this;//链式编程思想,返回调用者本身,但是一定要返回本身的引用
}
在成员函数后面加const,修饰的是this指针const ClassName * const this
,此时,const指向的值不允许发生修改。
map/multimap
在map中,所有的元素都会根据元素的键值自动排序。在multimap中,允许有相同的key值,而在map中则不允许。
#include<map>
map<T1,T2> mp;//默认构造函数
map(const map &mp);//拷贝构造函数
map.insert(pair<type,type>(para,para));//插入pair数据
map[3]="string"//数组方式插入
map<int ,string > ::iterator it;;
it = mapName.find(112);//查找,然后返回一个对应的迭代器。
iterator erase(iterator it)//删除一个条目
find(key)//若key值存在,则返回该元素的迭代器,若不存在,返回map.end()
count(key) //统计key的元素个数
结构体
自定义的结构体可用于存储不同的数据类型
(struct) StructName s = {...}
struct StructName{
...
}s;//在定义的时候直接创建一个变量
//创建结构体数组
(struct) StructName s[10] = {
{...},
{...},
{...}
}
//结构体指针
memset、memcpy和strcpy的区别
memcpy是内存拷贝函数,可以拷贝任何数据类型的对象,例如memcpy(b, a, sizeof(b))。
strcpy只能拷贝字符串,遇到’\0′结束拷贝。
memset用来对一段内存空间全部设置为某个字符,例如:char a[100];memset(a, '', sizeof(a))。
内联函数
编译时展开,将函数代码直接嵌入到目标代码中去,用于解决一些频繁调用的小函数大量消耗栈空间的问题inline type func() {};
而宏定义在预编译时展开,只是简单的文本替换。
编译的四个阶段
第一阶段:预处理阶段。根据文件中的预处理指令来修改源文件的内容。如#include指令,作用是把头文件的内容添加到.cpp文件中。
第二阶段:编译阶段,将其翻译成等价的中间代码或汇编代码。
第三阶段:汇编阶段,把汇编语言翻译成目标机器指令。
第四阶段:是链接,例如,某个源文件中的函数可能引用了另一个源文件中定义的某个函数;在程序中可能调用了某个库文件中的函数。
函数指针
int *a[10]; //一个有10个指针的数组,该指针是指向一个整型数的
int (*a)[10]; //一个指向有10个整型数数组的指针
int (*a)(int); //一个指向函数的指针,该函数有一个整型参数并返回一个整型数
int (*a[10])(int); // 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数
static
static数据成员独立于该类的任意对象而存在;static数据成员(const static数据成员除外)在类定义体内声明,必须在类外进行初始化
C++语法难点的更多相关文章
- mysql语法难点
select * from emp where comm is null or comm=0;/*没有提成的员工*/ 查询有提成的员工所有信息 select * from emp where comm ...
- (易忘篇)java基本语法难点1
switch后面使用的表达式可以是哪些数据类型 byte.short.char.int.枚举类型变量.String类型. 如何从控制台获取String和int型的变量,并输出 // 以下只关注重要点的 ...
- (易忘篇)java基本语法难点2
1.不同类型的一维数组元素的默认初始化值 整型元素 : 0 boolean型元素 : false 浮点型元素 : 0.0 char型元素 : 0或'\u0000',而非'0' 引用类型元素 : nul ...
- (易忘篇)java基本语法难点3
本博客随笔主要记录本人学习过程中的知识,欢迎大家一同学习,有不对的地方很高兴读者能详细指出,感激不尽! JVM内存结构 编译完源程序以后,生成一个或多个字节码文件. 我们使用JVM中的类的加载器和解释 ...
- (十)Linux内核中的常用宏container_of
Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址. Containe ...
- 全方位掌握 NSIS 的操作
NSIS 确实是一个不错的安装程序制作软件.新版本2.0a7真正实现了中文支持和支持 WinXP 的安装对话框.不过要用它实现漂亮的安装界面和完美的安装功能就必须好好的写脚本.而 NSIS 的脚本指令 ...
- Linux内核中的常用宏container_of
Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址. Containe ...
- contain_of宏定义
Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址. 实现方式: co ...
- 数据结构(c语言版)代码
第1章 绪论 文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲01 绪论 概述 第一章作为绪论,主要介绍了数据结构与算法中的一些基本概念和术语.对于这些概念术语 ...
- 2-2-求并集A=A∪B-线性表-第2章-《数据结构》课本源码-严蔚敏吴伟民版
课本源码部分 第2章 线性表 - 求并集A=A∪B ——<数据结构>-严蔚敏.吴伟民版 ★有疑问先阅读★ 源码使用说明 链接☛☛☛ <数据结构-C语言版>(严 ...
随机推荐
- fastapi四:uvicorn.run支持的参数
`app:指定应用app,'脚本名:FastAPI实例对象'.FastAPI实例对象 host: 字符串,允许被访问的形式 locahost.127.0.0.1.当前IP.0.0.0.0,默认为127 ...
- Django Rest Frame work 如何使用serializers序列化函数新手教程
Django Rest Frame work 如何使用serializers序列化 Django Rest Framework提供了serializers模块,用于序列化和反序列化模型实例 ...
- android cannot generate view binders android.databinding.tool.util.LoggedErrorException
错误: Cannot resolve type 'viewModel'错误: cannot generate view binders android.databinding.tool.util.Lo ...
- go 更新依赖库到最新版本
go 怎么更新依赖库到最新版本 遇到这么一个问题:我自己的一个程序依赖自己写的一个库,然后修改了库,程序这边想要更新库,却怎么也更新不上 删除mod.sum文件里相关库的信息 使用find / -na ...
- fix: because the volume group on the selected device also consist of physical volumes on other devices
because the volume group on the selected device also consist of physical volumes on other devices 目标 ...
- Git中常见的一些问题总结
Git中常见的一些问题总结 目录 Git中常见的一些问题总结 1.git添加到暂存区的修改,如果不想要了,怎么撤销 2.git添加到本地仓库,如果不想要了,怎么撤销 3.提交代码时发现别人已经提交了( ...
- HTML学习笔记6----链接
随笔记录方便自己和同路人查阅. #------------------------------------------------我是可耻的分割线--------------------------- ...
- Python学习笔记调式之抛出异常
随笔记录方便自己和同路人查阅. #------------------------------------------------我是可耻的分割线--------------------------- ...
- fragment加radio不可滑动
public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener { ...
- golang常见编程错误集
一.append是深拷贝, func main() { a := []int{7, 8, 9} fmt.Printf("%+v\n", a) ap(a) fmt.Println(& ...