语法
指针和引用
指针:存放某个对象的地址 引用:变量的别名,从一而终,不可变,必须初始化const变量
指针常量(底层const):指针所指的对象不可变 常量指针(顶层const):指针不可变define和typedef的区别
define:- 只是简单的字符串替换,没有类型检查
- 是在编译的预处理阶段起作用
- 可以用来防止头文件重复引用
- 不分配内存,给出的是立即数
- 有对应的数据类型,需要进行判断
- 在编译、运行的时候起作用
- 在静态存储区中分配空间
define和inline的区别
define:定义预编译时处理的宏,只是字符串替换,无类型检查,不安全。 inline:直接将函数体插入被调用的地方,减少了压栈,跳转和返回的操作。 内联函数是一种特殊的函数,会进行类型检查。override和 overload
override:重写,覆盖 overload:通过不同的参数类型,不同的参数个数,不同的参数顺序进行重载。访问权限,返回类型,抛出的异常不进行重载 总结:重写只有一个,重载是将类似的函数用同一个名字,仅通过参数区分 多态是为了避免在父类中进行过多的重载new和malloc
- new分配失败抛出异常,malloc返回nullptr
- new无需指定内存块的大小,malloc需要显示指出所需内存的尺寸
- new和delete可以重载,malloc和free不能重载
- new会调用对象的构造析构函数,malloc不会
- new是运算符,malloc是库函数
constexpr和const
constexpr:常量表达式 const:只读 constexpr的好处:确保某些数据无法被修改;部分场景编译器可以对constexpr做优化;比宏更安全,开销更少。volatile
作用:要求编译器读取数据时,每次都从内存中重新装载内容,而不是从寄存器中拷贝extern
定义:声明在函数或者文件外定义的全局变量static
作用:实现多个对象之间数据的共享和隐藏;默认初始化为0前置++与后置++
前置++返回左值(引用),后置++返回右值(临时对象)std::atomic
作用:为了线程安全,使得原本线程不安全的语句变成“原子”语句,不再可分,从而实现线程安全。访问权限
pubic:公有 protected:保护 private:私有 在类内(定义类的代码内),三种都可以访问。 在类外(定义类的代码外),只能访问public成员。 无论何种继承,派生类都不能访问私有成员。 对于公有继承,“派生类对象”只能访问基类中的公有成员。对于私有和保护继承,“派生类对象”无法访问基类的所有成员。 1. 继承 功能:在现有类的基础上,定义一个新的类,使得可以在无需重新编写的情况下,进行功能拓展。- 实现继承:使用基类的属性和方法,无需额外编码
- 接口继承:仅使用属性和方法的名称,具体实现由子类提供
- 可视继承:指子窗体类,使用了基窗体类的外观和实现。
- override(重写,覆盖):子类重新定义父类的虚函数。
- override(重载):允许存在多个同名函数,通过不同的参数列表区分。
虚函数(virtual)
功能:当基类希望派生类自定义函数时,将该函数声明为虚函数。- 虚函数是动态绑定的:使用虚函数的指针和引用可以找到实际类的对应函数
- 多态:前提条件(1)调用函数的对象必须是指针或者引用(2)被调用的函数必须是虚函数,且完成了重写
- 动态绑定绑定的是动态类型:虚函数对应的函数或属性依赖于对象的动态类型,发生在运行期。
- 构造函数不能是虚函数:在构造函数中调用虚函数,会执行父类的对应函数,因为自身还没有构造好,无法多态。
- 析构函数可以是虚函数,且在复杂类中,通常必须是虚函数。析构函数也可以是纯虚函数。
- 虚函数的工作方式:虚函数依赖虚函数表工作,表中保存虚函数地址,当用基类指针指向派生类时,虚表指针指向派生类的虚函数表
- 纯虚函数:有纯虚函数的类是抽象类,无法实例化。
- inline(编译时展开), static(静态), constructor(子类未构造) 三种函数不能为虚函数
- 派生类的虚函数重写定义必须与父类完全一致。
- 解决多继承(从多个直接基类中产生派生类)的命名冲突和冗余数据问题。(实际中最好不要用多继承)
- 解决菱形继承,典型案例:iostream从istream和ostream直接继承而来,而istream和ostream各自继承自同一个类baseios。
智能指针
shared_ptr 1.实现机制:在拷贝构造时使用同一份引用计数- 模板指针:指向实际的对象
- 引用计数:使用new,存放在堆中
- 重载operator* 和operator->:实现指针的效果
- 重载copy constructor:引用计数+1
- 重载operator=:对右边的shared_ptr 调用析构函数,对左边的调用拷贝构造
- 重载析构函数:使应勇次数减一,当引用为0时,delete
C++内存模型
字符串操作函数char *strcpy(char *strDest, const char *strSrc); //把src字符串拷贝到dest字符串上。 int strlen(const char *str); //计算给定字符串的长度 char *strcat(char *dest, cosnt char *src); //把src接到dest字符串的后面。 int strcmp(const char * s1, const char * s2); //比较大小。s1 < s2 返回负数 = 返回0, > 返回正数内存泄露 定义:程序未能释放掉不再使用的内存的情况,称为内存泄漏。可以使用Valgrind,mtrace进行内存泄漏检查 分类:(1)堆内存泄露:开辟的堆内存没有释放。(2)系统资源泄露:程序使用系统分配的资源(Bitmap, handle, SOCKET等),没有使用相应的函数释放,导致系统资源的浪费。(3)没有将基类的析构函数定义为虚函数,导致子类没有正常释放 常见情况:指针改变指向,未释放动态分配的内存 措施:将内存的分配封装在类中,构造分配,析构释放;使用智能指针 地址空间分布
- 命令行参数和环境变量:从命令行执行程序时,程序员指定的参数
- 栈区:存储局部变量、函数参数值。从高地址向低地址增长的连续空间
- 文件映射区:绑定动态库等
- 堆区:动态申请的内存。从低地址向高地址增长
- BSS段:存储未初始化的全局变量和静态变量
- 数据段:存储已初始化的全局变量和静态变量
- 代码段:存放程序代码的内存区,只读,头部包含一些只读的常数变量。
C++11新特性
类型推导
1.auto
作用:让编译器在编译期自动推导出变量的类型- 必须初始化
- auto不能定义数组
- 不能推导出模板参数
- 在不声明为引用或指针时,会忽略等号右边的引用类型,和const, volatile类型。
- 声明为引用或指针时,会保留。
2. decltype
decltype用于推导表达式类型。 decltype会保留引用和cv属性(const,volatile) 对于decltype(exp)有:- exp是表达式,decltype(exp)和exp类型相同
- exp是函数调用,decltype(exp)和函数返回值类型相同
- 其他情况,若exp是左值,decltype(exp)是exp类型的左值引用
template <typename T, typename U> auto add(T t, U u) -> decltype(t + u) { return t + u; }
右值引用
定义:右值引用就是必须绑定到右值的引用,通过&&来获得右值引用。 性质:只能绑定到一个将要销毁的对象,于是,我们可以自由地将一个右值引用的资源绑定到另一个对象中。 常规的引用,我们可以称之为左值引用。1.左值右值
左值:有地址,可以放在等号左边 右值:没有地址,不可以放在等号左边(字面量,临时量)++i, --i 是左值,i++, i-- 是右值。
2.右值引用
右值有两个特性:所引用的对象将要被销毁;该对象没有其他用户 这意味着:使用右值引用的代码可以自由地接管所引用的对象的资源 右值引用本身是一个左值:接管资源后,资源就有了地址和用户,因此,右值变成了左值。3.std::move
虽然不能把右值引用绑定到左值上,但可以使用std::move把一个左值转化为对应的右值引用类型。 浅拷贝:拷贝指针 深拷贝:重新开辟内存,并复制内容nullptr
nullptr:特殊类型的字面量。 用来替代NULL和0。NULL在有的编译器中定义为((void*)0),有的定义为0。因此,NULL具有二义性,在下面情况会发生问题。void test(char*); void test(int);使用test(NULL)时,编译器会不知道使用哪一个重载。
范围for循环
for (auto c : string) { cout << c; }可以简化遍历。
列表初始化
double d = 3.124564564654 int a = {d}; int a = d;使用花括号来进行初始化称为列表初始化。 对于内置类型,使用列表初始化时,如果存在丢失信息的风险,编译器会报错。
lambda表达式
表示一个可调用的代码单元,可以理解为没有命名的内联函数,用于一次性的场景。1.语法
[capture list] (parameter list) ->return type {functon body}我们可以忽略参数列表和返回类型,但必须永远包含捕获列表和函数体。
2.变量捕获
- []不捕获
- [&]引用捕获
- [=]拷贝捕获
- [=, &foo]引用捕获foo,拷贝捕获其他
- [bar]拷贝捕获bar
- [this]捕获所在类的this指针
3.lambda使用algorithm库
std::sort(arr, arr+6, [](int &a, int &b){return a > b});标签:知识点,函数,右值,速刷,内存,c++,对象,引用,指针 From: https://www.cnblogs.com/yuan-sen/p/16664305.html