
C++温故补缺
文章平均质量分 70
chocolate7777777
这个作者很懒,什么都没留下…
展开
-
C++温故补缺(二十一):杂项补充2
我们在函数 foo 中使用了 A 类型的参数,然后在 main 函数中分别使用了显式调用构造函数和隐式类型转换来创建 A 类型的对象,并尝试将这些对象作为参数传递给函数 foo。其中,第一个参数 ptr 是指向内存块的指针,第二个参数 value 是要设置的值(通常是 0 或 -1),第三个参数 num 是要设置的字节数。在C++中,有时需要使用嵌套的类型名称,如类模板中的类型别名或嵌套类的名称等。assert是用来排除错误的,而if是用来找异常的,错误是可以通过修改去掉的,而异常是无法避免的。转载 2023-06-08 09:19:32 · 142 阅读 · 0 评论 -
C++温故补缺(二十):杂项补充1
和C相同都有auto,extern,static,register存储类,并新增mutable和thread_local(C++11):C语言中auto用来声明函数内的变量,C++98标准中和C相同.C++11后,auto用来定义自动推导的类型,且必须在定义时赋初值.c语言中表示布尔型一般用0/1,或者flag,c++把布尔型内置了,布尔型的变量只有true和false 两个值。先运算a++ =>a=0,然后运算a-99,a-99并不会对a做影响,所以无效,最后返回a+2,也就是3。转载 2023-06-07 11:50:31 · 88 阅读 · 0 评论 -
C++温故补缺(十九):atomic类
C++11 中的原子类型的API大都需要提供一个std::memory_order(内存序,访存顺序)的枚举类型作为参数,如atomic_store, atomic_load, atomic_exchange, atomic_compare_exchange, atomic_flag, 以及还有test_and_set和clear等API都可以设置一个std::memory_order参数。静态内存模型主要涉及类的对象的在内存中是如何存放的,即从结构上来看一个对象在内存中的布局。转载 2023-06-07 11:48:10 · 862 阅读 · 0 评论 -
C++温故补缺(十八):lock类
defer_lock是暂时先不加锁,和未上锁的状态是一致的,而adopt_lock假设线程已经获取了锁,在mutex对象中,有个m_owns参数,也就是前面说的ownership,被谁获取了,这个值表示是否被调用的线程获取mutex对象的所有资源。但是并不是上锁的意思,上锁的参数是mutex对象的数据域的_lock值控制的,defer_lock和未上锁的状态一致,m_owns为false,data域的_lock值为0。当使用lock()手动上锁时,m_owns为true,data域的_lock值为1。转载 2023-06-07 11:43:17 · 155 阅读 · 0 评论 -
C++温故补缺(十七):mutex类
当首次遇到加锁失败的互斥量时,停止对后续互斥量的加锁,并解锁前面的互斥量,返回首个加锁失败的互斥量的序号。当线程请求被占用的锁时,用lock方式请求,会阻塞当前线程,无限时间,直到锁被释放。下面模拟之前说过的打印机的情况,就是多线程访问打印机,其中A线程在装入信息后被阻塞,打印机中的数据就会被线程B覆盖,当A恢复执行时,打印机中的数据仍然是B的数据。try_lock()方式请求锁时,会有一个设定好的最大时间,当在这个时间内没有获取到锁,线程会放弃请求锁,直接继续执行后续的代码。就获得了正确的打印结果。转载 2023-06-07 11:42:41 · 156 阅读 · 0 评论 -
C++温故补缺(十六):this_thread类
本来该并行执行的多线程任务,被指定到单个CPU上并发执行,当运行到yield暂停当前线程,执行其他线程,之后再返回继续执行。sleep_for()要和std::chrono::seconds,minutes,hours连用,设定暂停的时间。为了展示yield的效果,把程序绑定到一个cpu上处理。sleep_until和chrono::system_clock连用,设定暂停到一个时间点。放弃当前线程占用的时间片,使CPU重新调度以便其他线程执行。并且在编译时需要链接pthread库。BASH 复制 全屏。转载 2023-06-07 11:37:47 · 161 阅读 · 0 评论 -
C++温故补缺(十五):多线程
传统C++(C++11之前)中并没有引入线程的概念,如果想要在C++中实现多线程,需要借助操作系统平台提供的API,如Linux的<pthread.h>,或windows下的<windows.h>join会阻塞父线程,等待子线程执行完,父线程才结束。而detach不会等待,一旦父线程执行完,未执行完的子线程被释放掉。从C++11开始提供了语言层面的多线程,包含在头文件<thread>中,它解决了跨平台的问题,并提供了管理线程,保护共享数据,线程间同步操作,原子操作等类。采用多线程和单线程执行两个函数对比。转载 2023-06-07 11:37:26 · 54 阅读 · 0 评论 -
C++温故补缺(十四):信号处理
信号是由操作系统传给进程的中断,能够提前终止一个程序。函数的第一个参数是一个整数,代表了信号的编号,第二个参数一个指向信号处理函数的指针,也就是要把一个函数传进去当参数。下面是可以在程序中被捕获的信号,并且可以基于信号采取适当的动作,这些信号定义在C++头文件<csignal>中。signal()的第二个参数是捕获到信号后用来执行动作的函数,其参数就是前面该信号的整型值。signal()的第一个参数是定义好的可以捕获的信号,如上SIGINT就是用来捕获。raise()函数用来主动生成信号,参数为一个整数。转载 2023-06-07 11:04:38 · 126 阅读 · 0 评论 -
C++温故补缺(十三):模板
那么在模板中,确定模板类型后,假设为student,就会因为student没有getTno()和getTname()字段而无法通过编译,因为模板T识别为student是发生在编译阶段的,一旦确定为student,模板类中所有的T都会被替换成student,所以就出现"student类无getTno()和getTname()成员"的错误。如上,Max函数可以作用于不同的类型的参数,它会根据参数的类型自动转换模板类型T的类型,T只是一个名字,用来标志模板的类型。就是用来定义类模板的,后续可以指定为不同的类型。转载 2023-06-07 10:58:04 · 47 阅读 · 0 评论 -
C++温故补缺(十二):动态内存
同C,C++中也是有堆和栈的概念。栈是函数内部声明的所有变量都所占用空间,堆是程序中未使用的内存,在程序运行期间可用于动态分配。除此之外,new还可以在给对象分配内存空间的同时创建对象。同样也有alloc()分配内存,新增了new和delete运算符来分配释放内存。用完之后可以用delete关键字释放内存。,并返回一个该类型的指针,new和delete。转载 2023-06-07 10:57:56 · 51 阅读 · 0 评论 -
C++温故补缺(十一):异常
如上,在遇到异常时,throw抛出一个表达式,可以是任意类型的,但是catch时要和throw抛出的表达式类型相同,如这里抛出-1,catch就要捕获int,如果抛出了"exception"这样的字符串,catch就要捕获const char*类型。第三方库的异常解释可读性很差,甚至需要查手册才能知道什么异常,比如直接抛出一些数值,像windows系统中常见的error:-1,error:#0x0081之类的,根本不可能通过这些信息知晓异常的详情。但是可以处理,通过抛出,捕获异常,C++标准库中的异常类。转载 2023-06-07 10:49:14 · 46 阅读 · 0 评论 -
C++温故补缺(十):C++文件读写和流
从文件读取信息或向文件写入信息之前,必须先打开文件,用到open()函数,open()函数是fstream,ifstream,ofsteam对象的一个成员。file.eof()是文件对象的成员,当读到文档的结尾时,会返回一个EOF标志,eof()函数当遇到EOF标志时,返回boolean的true。虽然程序终止时,会自动关闭刷新所有的流,释放所有分配的内存,并关闭所有打开的文件,但最好还是在程序终止前用close()函数关闭文件。就是以写入模式打开文件,且如果文件已经存在,就把之前的内容截断。转载 2023-06-07 10:45:05 · 139 阅读 · 0 评论 -
C++温故补缺(九):C++多态
那么这个函数就是一个纯虚函数,纯虚函数所在的类,只能被继承,不能用于实例化,类似java中的抽象类。并不是想象中的两个面积,这是因为调用shape->area()是基类中的area()函数,这就是。声明的函数,在派生类中重新定义基类中定义过的虚函数时,会告诉编译器不要静态链接到该函数。这样程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。,函数调用在程序执行前就准备好了,也被称为。如果定义虚函数=0,如。转载 2023-06-07 10:34:56 · 101 阅读 · 0 评论 -
C++温故补缺(八):运算符重载和函数重载
obj1是发生重载的对象本身,用this调用其成员;重载是c++多态性的一大体现,重载运算符是给运算符添加新的定义,使之前不能运算的对象变得可运算,且一般和运算符的意义相似.运算符重载一般作用于类的对象运算,因为它需要相同返回类型和参数,运算符重载依赖关键字。函数重载主要是同名函数参数类型不同,参数个数不同,实现不同的功能。函数重载体现在相同的函数名和不同形参列表上,和java等都类似。运算符重载不止可以在类中实现,还可以在结构体中实现。可重载的运算符和不可重载的运算符。:成员指针访问运算符。转载 2023-06-07 10:34:31 · 63 阅读 · 0 评论 -
C++温故补缺(七):;类的访问控制和继承
静态变量在类的所有对象中共享,不能再类的定义中初始化,但可以在类外部通过作用域符。而普通成员函数可以访问所有的,包括静态和非静态的成员。类的静态成员函数可以直接被类调用,不需要初始化对象。修饰,类似静态变量或静态函数,也是有共享的概念。静态成员函数没有this指针,只能访问静态成员。引用变量:必须通过构造函数参数列表初始化。基类的构造函数,析构函数和拷贝构造函数。静态变量也是有作用域的,需要。,可以在定义的时候直接初始化。静态非整型常量:要在类外通过。来初始化,或通过对象初始化。类的静态成员用关键字。转载 2023-06-07 10:32:05 · 63 阅读 · 0 评论 -
C++温故补缺(六):友元函数、内联函数和this指针
this指针this指针是指向对象本身的指针,在所有的成员函数的参数都隐含了this指针,可以通过this指针调用所有的成员。转载 2023-06-07 10:26:35 · 127 阅读 · 0 评论 -
C++温故补缺(五):移动构造函数
也就是前面说的move语义,剥夺而非拷贝的方式获取资源。特别,move函数可以生成一个和它的参数t有关联的xvalue(指资源可以再利用的对象)表达式。也就是move会返回和参数类型相同的类型的表达式。首先介绍移动语义(move),指以移动的方式而非深拷贝的方式初始化含有指针成员的类对象。一般认为,移动资源后,原来的参数就不会再被访问到,为了保证这一点,需要手动置零/置空/释放内存,这也是对前面"高效"的解释。对于no-pod类型,move是以移动的方式获取资源,而pod类型,则是直接复制。转载 2023-06-07 10:24:33 · 198 阅读 · 0 评论 -
C++温故补缺(四):构造函数和复制构造函数
默认的复制构造函数实现的只是。转载 2023-06-07 10:11:35 · 57 阅读 · 0 评论 -
C++温故补缺(三):基本输入输出
每个流插入到cerr后会立即输出,而clog对象是缓冲的,每个流插入到clog会先存储在缓冲区,直到缓冲填满或缓冲刷新才输出。虽然看上去功能无差别,但最好还是用cerr输出错误信息,clog输出日志,不要全都用cout。在功能和调用上,cout,cerr和clog看上去无差别,cerr对象是。转载 2023-06-07 10:09:58 · 74 阅读 · 0 评论 -
C++温故补缺(二):lambda函数
通过值传递方式捕获的变量在lambda中默认是const类型,只能输出,不能改变,使用mutable可以使其可变,但是只能在lambda中短暂使用,并不能影响到父作用域的变量。通常,lambda函数用于封装传递给算法或异步方法的几行代码,对应不需要复用,且短小的函数,使用lambda函数可以增加代码的可读性。可以使代码结构更紧凑,因为调用的函数的定义就在旁边,不用向前后向后找,可读性更好。[=,&a,&b]:以值传递的方式捕捉其他所有变量,以引用方式捕捉a,b。不能省略,可以使空的参数列表,但。转载 2023-06-07 10:07:05 · 96 阅读 · 0 评论 -
C++温故补缺(一):引用类型
C++的左值和右值是从C语言继承过来的,左值的英文简写是"lvalue",右值是"rvalue"。左值的本意是"loactor value",即"可定位的值",也就是存储在内存中、有明确的存储地址的数据,或者说可寻址的数据。而右值"read value",指仅提供数值的数据,不一定可以寻址,如存储在寄存器中的数据。通常,简单区分左值右值就看赋值号(=)的左右侧,能放在左侧的就是左值,只能放在右侧的是右值。在C++98/03中,就有引用,用‘&’表示,但是不能对数值引用只能引用定义好的变量。转载 2023-06-07 09:56:09 · 55 阅读 · 0 评论