- 博客(111)
- 资源 (1)
- 收藏
- 关注
原创 3.6 POD类型
所谓POD,全称为Plain Old Data,表示普通的旧数据类型,这种类型不存在C++的虚函数和许捷诚等数据,体现了其与C的兼容,可以使用用最老的memcpy()函数进行复制,使用memset()进行初始化等。
2023-12-23 11:44:38
429
原创 4.5 基于范围的for循环
值得指出的是,使用范围for需要一些条件。首先,要求被迭代的对象的范围是可确定的,比如容器累的begin,end,或者是数组的起始位置和结束位置,这些都是用于确定遍历范围。范围for分为两部分,前者ele为迭代元素(注意不是迭代器,是可以直接访问的元素),后者eles则是被遍历的容器。对于正常的stl和内置数组而言,都是符合这些要求的,但是如果用户自己实现,则需要注意实现这些内容。但是上述两种方式都需要告诉循环体其界限的范围。当然需要注意auto不会推导引用,需要自己写。
2023-12-23 11:23:57
462
原创 4.1 右尖括号>的改进
而在C++11将这个限制取消,要求编译器“智能”判断是什么类型。当然,正常场景下也不会这么用,此外,如果真的出现这样的场景,我们还可以将1>>5用括号包裹,提高优先级,从而解决。很显然,我们需要的是右移操作,但是由于C++11对于右移操作符的优化,上面代码会报错。C++11之前对于双右尖括号优先解析为右移操作符,因此一些场景下会导致编译报错,所以,在之前需要在这些场景下将两个>用空格分隔。
2023-12-22 15:43:52
454
原创 4.4 追踪返回类型
这一条通常是对于多层函数而言(更像是面试题)// 有的时候,你会发现这是面试题// auto (*)() -> int(*) () 一个返回函数指针的函数(假设为a函数)// auto pf1() -> auto (*)() -> int (*)() 一个返回a函数的指针的函数// 1定义了两个类型完全一样的函数pf和pf1。其返回的都是一个函数指针。而该函数指针又指向一个返回函数指针的函数。这一点通过is_same的成员value已经能够确定了。
2023-12-22 15:43:22
586
原创 4.3 decltype
可以推导模板的返回类型从而使用引用参数获取返回值,当然这里仍然需要声明实参,所以还是需要知道具体类型,用法比较鸡肋,牛逼的是后面的追踪返回类型。decltype能够继承cv限制符、引用和指针,但是只是针对声明本身,对于对象如果是cv的,其成员类型于成员本身是否cv有关(下例的a.i)而在C++11中,又增加了hash_code这个成员函数,返回该类型唯一的哈希值,以供程序员对变量的类型随时进行比较。对于cv以及&,如果推导的类型已经有了,而又指定了,则通常会忽略decltype()后的cv和&。
2023-12-21 09:04:07
840
原创 4.2 auto类型推导
上述代码radius未float类型,而在经过计算之后得到的circumference精度得到了扩展(double),而有时我们容易依赖原有类型将circumference声明为float类型,这就使得计算结果精度降低了。auto在进行类型推导时,会对auto后冗余的*进行忽略,如p通过自动推导为int *,而auto*则不会被认为是int **,而是int *。3)声明auto数组。我们可以看到,main中的x是一个数组,y的类型是可以推导的,而声明auto z[3]这样的数组同样会被编译器禁止。
2023-12-21 09:03:20
729
原创 3.4 显示转换操作符
所谓自定义类型转换,是相对于标准隐式转换而言的,需要用户自己实现,分为转换构造函数和自定义类型转换函数。类似于构造函数,在类A中形如的成员函数,意味着可以将A隐式转换为A类型。class A {};B b = a;testA(b);//自定义类型转换如上面的例子,20行的testA函数需要A类型的参数,这里传入了b也可以完成调用,是因为发生了隐式类型转换。风险:上面的testA()函数可能还看不到什么危害较大的风险。
2023-12-20 11:25:46
390
原创 3.3 右值引用:移动语义与完美转发
想要解决上述的问题,我们可以通过“偷”的方式,减少拷贝时内存分配,即将原有的资源浅拷贝到新对象的资源句柄上,而原资源置空,这样“偷”的方式叫做移动语义,这样的构造函数称为移动构造。只有再赋值给其他变量时,才会通过移动构造或者移动赋值,将a的资源移走,但是a依旧不会被释放,只不过因为移动语义的作用,其资源无法被访问了。实际上,默认的移动语义(移动构造)与拷贝并无区别,因此想要实现资源的移动构造,需要自己实现。此外,默认移动构造与拷贝构造并无区别, 所以想要实现资源移动的移动构造,需要自己实现。
2023-12-19 09:14:27
1034
原创 3.2 委托构造函数
构造函数在初始化列表位置,调用其他构造函数进行初始化,从而降低代码重复率,这样的构造函数成为委托构造函数,(在初始化列表位置)被调用的构造函数称为目标构造函数。class A {public:} //委托构造函数} //委托构造函数private:int main()A a,b(1);
2023-12-19 09:13:42
419
原创 3.1 继承构造函数
C++11将通过using声明使用基类函数的方式扩展到了构造函数上,使得子类能够使用到父类一样的构造函数,这种构造方式称为继承构造函数。//继承构造private:int b{1};//就地初始化int main()/*print:A()A(int)*/
2023-12-18 09:28:33
167
原创 第2章 保持稳定性和兼容性
C++11中增加了以下宏:实际验证vs2017只支持__STDC_HOSTED__获取函数名。//main需要注意的是不支持在函数默认参数,因此此时__func__还没有被定义。int x = 3;// 一些代码...// 编译选项:g++ -std=c++11 2-1-5.cpp。
2023-12-18 09:28:00
82
原创 5.1 C++11强类型枚举
强枚举类型也是可以匿名的,但是由于其枚举成员需要通过作用域访问,因此匿名强枚举类型可能无法访问成员,当然也可以使用decltype获取类型。因为C的枚举是基于常量数值设计的,所以总是可以被隐式转为int,所以在算数运算(没有什么意义)和比较运算时,容易出错。枚举值和类型都是全局可见的, 与正常C++的namespace、类等都是格格不入的,并且还容易导致冲突。其次,在C++11中,枚举成员的名字除了会自动输出到父作用域,也可以在枚举类型定义的作用域内有效。
2023-12-16 11:33:11
127
原创 5.2 C++11堆内存管理:智能指针与垃圾回收
通过引用计数的方式,每有一个指针引用此内存时,计数+1,相反,每有一个指针不再引用此内存时,计数-1。第一步扫描,第二步移动,移动的方式是将空间分成from和to两部分,将当前活的对象坐在区域为from,然后移动到to空间内,然后将from空间清空,并将from和to的定义互换。C++一些垃圾回收的库,但是由于指针的灵活性(指针可能做了移动,但是原来的内存并不一定被释放,可能还会移回继续使用原来的内存),所以只是最小垃圾回收支持。指针指向的内存释放之前,先释放了指针,导致那块内存无法访问,且无法重新使用。
2023-12-16 11:32:22
147
原创 6.2 C++11变长模板
对于声明了的变长模板参数包Args,如果我们使用Args&&...的方式解包,意味着展开后的参数为Arg1&&,Arg2&&,...,Argn&&。C++11引入变长模板的同时,扩展了sizeof,引入了sizeof...,用于计算参数包的参数个数,需要注意的是传入的参数为包名,而非形参名。值得注意的是,在C++11中,标准要求函数参数包必须唯一,且是函数的最后一个参数(模板参数包没有这样的要求)。值得注意的是,在C++11中,标准要求函数参数包必须唯一,且是函数的最后一个参数(模板参数包没有这样的要求)
2023-12-15 09:13:10
128
原创 7.3 lambda函数
而lambda较for_each而言,首先其函数内容会直接放在调用处,可阅读性更高(当然,有时也会被分离出来并命名,但通常不会太远);其次使用函数指针很可能导致编译器不对其进行inline优化(inline对编译器而言并非强制),在循环次数较多的时候,内联的lambda和没有能够内联的函数指针可能存在着巨大的性能差别。lambda函数中不同的捕获传递方式会造成不同的结果,对于值传递,则在传递的值在编译期就确定了,无法被修改,而对于引用传递则可以同步lambda函数外的修改。
2023-12-15 09:12:22
403
原创 6.4-6.5 C++11线程局部存储与快速退出:quick_exit与at_quick_exit
上面的例子中使用全局的errorCode作为错误码,这样方便保存线程中的错误码,但是对于多线程二线,可能存在错误码覆盖的问题,比如thread1的错误码1和thread2的错误码-1可能会相互覆盖。C++中存在正常退出和异常退出两种情况,其中异常退出主要是对于发生异常而未被捕获时产生,此时会调用terminate,而terminate默认行为是调用abort函数终止程序,当然也可以通过set_terminate修改默认行为。C++11对TLS标准做出了一些统一的规定。
2023-12-14 17:20:11
221
原创 一个简单的cmake模板(C++)
这是一个基于CMakeLists.txt创建的C++模板项目。它提供了固定的目录结构:src目录存放源码externals目录存放依赖(库),bin目录存放生成的产物install目录存放打包安装内容通过clone这个项目,可以快速的使用CMakeLists.txt文件,选择与项目相关的配置(默认提供最简单的可执行文件所需要的CMake配置),从而快速开始代码编辑,而不是到处寻找cmake命令目前支持的cmake内容有:1.项目名(project)
2023-12-14 14:38:37
930
原创 6.3 C++11 原子操作与原子类型
创建自定义类型的原子类型,当然也可以使用此方式创建内置类型的原子类型。atomic为作为类模板,提供了统一的操作接口:其中is_lock_free用于判断是否有锁,load用于读取,store用于存,exchange用于交换数据。由于原子类型属于资源类型,所以为了避免拷贝时引起的问题,atomic类模板删除了相关的拷贝构造和赋值函数。此外,atomic到原始类型的转换也是允许的(隐式的),但非原子操作。
2023-12-13 21:43:24
1034
原创 6.1 C++11 常量表达式
而对于j,如果不是有代码显式地使用了它的地址,编译器可以选择不为它生成数据,而仅将其当做编译时期的值(是不是想起了光有名字没有产生数据的枚举值,以及不会产生数据的右值字面常量?对于浮点数常量,由于编译时和运行时环境可能不同,这样就会导致浮点数常量的精度可能有所变化,因此在C++11中,要求编译时的浮点常量表达式值的精度要至少等于(或者高于)运行时的浮点数常量的精度。而由于constexpr的编译时常量性,使得对于递归的常量表达式函数的使用,并不会带到运行时展开计算,而是在编译时直接计算好结果进行替换。
2023-12-13 21:42:34
143
原创 7.2 C++11默认函数的控制
按explicit的本意是无法通过编译的,但是此处添加了=delete之后,反而移除了explicit的本意。而言,对于Func('a');显示缺省,对于默认生成的函数而言,并不是默认所有都会生成,而是在需要时才会生成。而且当用户自己实现其中的某个函数时,编译器就会移除相应的默认函数,这样就会导致类变得不是POD了。C++11提供了=default关键字,用于默认函数定义之后,表示要求编译器生成对应的默认函数,从而确保类的POD。除此之外,还可以用于删除new函数,使得类只能创建于栈,而不能创建于堆上。
2023-12-11 09:14:26
175
原创 7.1 C++11指针空值—nullptr
比较运算也有区别,nullptr可以与任意指针或nullptr_t类型以及0比较(非0整数不允许),而NULL可以与整数和指针比较。nullptr可以隐式转换为任意指针类型,而NULL需要显示转换。nullptr_t类型是由nullptr获取的。NULL可以进行算数运算,nullptr不行。NULL是宏定义,nullptr是关键字。
2023-12-11 09:13:19
109
原创 7.2 C++11默认函数的控制
这里对于explicit ConvType(char c)函数而言,意味着拒绝从字符char隐式转换为ConvType类型,因此 Func('a');显示缺省,对于默认生成的函数而言,并不是默认所有都会生成,而是在需要时才会生成。而且当用户自己实现其中的某个函数时,编译器就会移除相应的默认函数,这样就会导致类变得不是POD了。C++11提供了=default关键字,用于默认函数定义之后,表示要求编译器生成对应的默认函数,从而确保类的POD。除了在类内指定default外,也可以在类外指定,
2023-12-08 09:34:13
70
原创 C++11 智能指针
接口作用构造函数。创建一个auto_ptr对象,并管理指针_Ptr的释放析构函数。释放管理的指针_Myptr重载*操作符获取当前 auto_ptr 指针指向的数据。重载 ->操作符,当智能指针指向非基础类型时,通过 -> 运算符可以获取其内部的指定成员。重载 = 操作符,从而将一个相同类型指针的auto_ptr赋值给当前auto_ptr,当前auto_ptr获得指针的所有权。get()获取当前 auto_ptr 指针内部包含的普通指针。release()
2023-12-07 15:30:53
346
原创 8.3 C++11对Unicode的支持
在C++98中,引入wchar_t对Unicode支持,但是后来由于不同平台下wchar_t的宽度并不相同(8,16,32位),导致可移植性受到影响。此外,对于多个连续声明的字符串常量,只要有一个有前缀,则编译器会将这些连续的字符串常量都以此前缀处理。(实际上vs2017并不允许)通常情况下,对于连续的字符串常量,C++会要求编译器将其连起来,比如"a" "b"和"ab"没有区别。以上三种,再加上wchar_t格式的L以及不带前缀的字符串,C++11则包含了5种字符串常量的前缀。
2023-12-07 15:20:37
311
原创 8.2 C++11通用属性
上述例子中因为函数Func中的条件语句有悬挂(else没有处理),所以当传入0时,并不会抛出异常终止程序,与noreturn的属性冲突,执行了12行代码,但是最终在return时发生异常崩溃。随着C++语言的演变和编译器的发展,人们常常发现C++的标准提供的语言能力不能完全满足要求,因此各大编译器厂商为了满足客户需求,设计出一系列语言扩展来扩展语法,比较常见的就是“属性”。用于标识不会返回的函数的。主要用于那些不会将控制流返回到调用函数的函数,如终止程序的函数,无限循环语句的函数,抛出异常的函数等。
2023-12-07 15:20:05
75
原创 8.1 C++11对齐支持
很显然,这样在push_back时,将一个对齐值为32的ColorVector塞到对齐值只有1的arrCV.data中,可能会导致一些性能上的丢失(虽然这里我实验了一下也没有什么区别~~~)代码中成员a占1个字节,成员b占4字节,而通过offsetof(用于获取成员变量在类中的偏移量),查看a,b成员位置时,b的位置为4而不是1,这是因为C/C++对数据结构有着对齐要求。内存对齐是一个整数,意味着该数据成员地址只能位于内存对齐的倍数上,如b位于4而非1。
2023-12-07 15:18:57
186
原创 git通过fork-merge request实现多人协同
(需要再本地拉取source repository代码,解决完冲突后重新提交到user repository中,如果之前的merge request没有关闭,则会将当前提交记录更新到刚刚的merge request中,然后就可以合并了。其次是fork出来的user repository是完全独立的,完全可以在其上开辟新分支、打标签等操作,而不影响source repository,使得source repository更加干净。至此,仓库就搭建好了,可以在本地进行开发,后续进行提交与合并。
2023-08-24 11:28:33
865
原创 cmake扩展(5)——file命令排除部分文件
获取所有文件(1,2,3,4.cpp,5.cpp)。而我们如果想要排除cpp文件的话,无法直接排除。在cmake中可以使用file命令获取需要的文件,并且支持正则/通配符,使用起来还是很方便的。list的REMOVE_ITEM命令表示从list中移除部分元素内容,这样,就可以排除掉不需要的文件啦。然后在使用list命令。
2023-08-18 17:03:42
4891
原创 解决QWebEngineView在linux下加载本地html失败的问题
而在linux(uos x86)下运行时,却发现加载失败,变成空白页面。查了半天原来linux下需要在路径前面加上"file://"。比如,对于路径"/home/code/test/test.html",则需要改成"file:///home/code/test/test.html"。除此之外,对于windows下可以直接使用QString传入到load和setUrl两个函数中,会自动隐式转换为QUrl类,而在linux下这样的代码不会报错,但是加载也是失败的。
2023-08-14 09:47:12
1295
1
转载 cmake扩展(4)——解决linux库版本冲突问题
通过添加这两个标志(其中任意一个都可以),表示当前库以及引用的库并不对外导出接口,且因为是静态库,所以当前库调用的opencv则被打包到静态库中,调用时无需链接外部的相关动态库,因此解决了opencv符号冲突的问题。在一个项目中引用了两个自己开发的库,而这两个库都直接或间接的调用了opencv,且两者调用的opencv版本不一样,导致打包运行时opencv符号冲突,导致崩溃。
2023-08-11 15:42:57
456
原创 cmake扩展(2)——windows下动态设置输出文件(dll/exe)版本
这里因为是按照我们设想的git tag版本格式(x.x.x),并根据git describe会自动返回"version-提交次数-g当前提交hash"内容所写的。另一种方式是通过cmake的PROJECT_VERSION,PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR, PROJECT_VERSION_PATCH, PROJECT_VERSION_TWEAK来获取,但是无法动态调整版本号,需要手动修改。这里我们根据模板做了一定的修改。
2023-08-11 11:06:18
1531
原创 cmake扩展(1)——VS+CMake创建Qt项目
在一开始时,CMakeLists文件中add_executable没有添加WIN32配置,会导致每次运行时,除了ui窗口,还会弹出控制台窗口。上面提到的ui文件类名为Form,这是创建Qt Widgets Form File文件默认的类名,暂时没有发现预设的操作。项目右键->添加->新建项->Qt->Qt Widget Form File。为了解决这个问题,可以在右键->属性->链接器->系统->子系统,选择窗口;项目右键->添加->新建项->C++类。此时一个待ui的类就添加好了,可以在项目中使用了。
2023-08-11 11:04:57
2058
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人