![](https://img-blog.csdnimg.cn/20201014180756754.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++
文章平均质量分 58
C++技术
mrbone11
这个作者很懒,什么都没留下…
展开
-
C++-三目运算符注意点与临时变量的坑
上述代码的最后一行会导致crash,原因在于,三目运算符返回的是一个左值,即可以看作是一个临时变量,我们知道变量都有且只有一个类型,由于我们getName()的返回值是一个string,所以临时变量就是string类型,此时如果三目运算符条件为假,那么就将一个0值(nullptr)赋给了一个string,而这会导致程序崩溃。这里我们的问题在于忽略了三目运算符返回的是一个左值(变量),并且让表达式在条件为真和假的时候返回的类型不兼容导致的。,然后返回的值作为三目运算符的条件。原创 2024-03-27 23:53:04 · 243 阅读 · 0 评论 -
C++-获取struct成员变量的偏移量
将表达式从内向外解析,首先给出0地址或者使用nullptr均可,然后强转成结构体指针类型,接着访问成员a,然后取a的地址,由于一开始给出的地址是0地址,所以a的地址便是相对于结构体起始地址的偏移量。改变struct member顺序。原创 2024-03-24 15:51:06 · 186 阅读 · 0 评论 -
C++-gdb调试常用功能
gdb调试常用功能如下,其中bin为要调试的程序,arg为参数### 启动gdb- 启动调试 gdb bin- 带参数启动 gdb --args bin arg1 arg2- so预加载LD_PRELOAD=/path/to/lib.so && gdb bin### 运行程序- r 开始运行程序- r arg1 arg2以参数启动程序### 设置断点原创 2024-01-25 22:17:14 · 471 阅读 · 0 评论 -
C++-LD_PRELOAD
LD_PRELOAD是linux上的一个环境变量,作用是在程序启动前先加载这个动态链接库(无论程序本身是否需要)。原创 2023-12-17 16:01:50 · 162 阅读 · 0 评论 -
C++-空指针调用不会引起crash
注意:在C++中对nullptr的访问是undefined behavior,虽然大多数时候实际不会造成崩溃,但我们不能依赖这种未定义的行为,因为它可能崩溃也可能不崩溃,跟编译器也有关系,还是应判断空指针,避免这种情况发生。,类方法是类的一部分,而非对象的一部分。可以看到对方法的调用跳转的位置是一样的,这证明了类方法是类的一部分而非对象的一部分,调用后走到。将ra引用绑定到对pa的取值上和调用func都可以正常执行,不会导致崩溃,这是。,汇编对应的代码将会基于0地址取对象中的n的值,此时才会造成崩溃。原创 2023-12-05 23:29:15 · 215 阅读 · 0 评论 -
C++-一些关于C++、你可能忽略的知识点(更新中)
变量并指向一个字符串常量,虽然不带const,但不应改变其字符串内容,因为这是一个undefined behavior,这个字符串常量存储的位置是可执行文件的代码段,该段仅可读而不可写。如果要声明可以改变其指向内容的char。的区域,我们改变的不是字符串常量本身,而是s指向的内存区域,第一句代码执行后,字符串常量的内容已经拷贝到可读写的栈中。此时s指向的地址在栈上,因此可以改变其指向的内容,声明一个不带const修饰符的char。可以直接使用TestClass::A。:字符串常量永远存储在。原创 2023-11-28 22:26:11 · 418 阅读 · 0 评论 -
C++-标准库 std::pair介绍
第三个构造函数的含义是,将first_args tuple中的元素作为参数传递给first类型的构造函数,first_args tuple中的元素作为参数传递给second类型的构造函数,piecewise_construct_t是一个struct类型。std::piecewise_construct是std内部声明的一个变量,t中的1和2.22将作为Foo类的构造函数参数传入。前两个构造函数是我们常见的形式,传递一个实参给first,另一个实参给second,并支持move语义和隐式类型转换的支持。原创 2023-10-15 23:25:41 · 661 阅读 · 0 评论 -
C++-标准库 nullptr关键字
nullptr被自动转换为各种pointer类型,但不会被转换为任何整数类型,它拥有类型std::nullptr_t,定义于,是一个基础类型。原创 2023-10-07 23:20:14 · 103 阅读 · 0 评论 -
C++-使用clang-format格式化代码
我的解决方法是在https://github.com/llvm/llvm-project/releases下载LLVM-16.0.5-win64.exe。windows下,在.pro目录下创建.clang-format文件,linux下,在用户目录创建.clang-format文件。,解压后在bin下找到clang-format.exe,修改Clang Format command为exe。重启后,点击工具->选项->Beautifier->Clang Format,选择使用File定义风格。原创 2023-08-08 23:09:43 · 532 阅读 · 0 评论 -
C-lex yacc入门看这篇就够了
当我们面对一个具有一定语法规则的文本内容,如log文件,CMakeLists.txt,甚至某种编程语言的源文件,希望提取出其中的有用信息时,我们该如何做?最简单的方式就是使用逐字或者逐行读取的方式,根据文本的规则去编写if条件语句,判断是否已经碰到了我们希望读取的内容,如果是则提取信息,否则跳过。对于具有复杂规则的文本,这么做的效率很低,并且不够优雅。我们可以使用lex yacc来帮助我们进行这项工作。lex允许将一个名字(name)和正则表达式关联起来,称之为定义(definition)原创 2023-06-29 22:24:04 · 862 阅读 · 0 评论 -
Effective C++-条款47 使用traits class表现类型信息
std::advance函数是一个工具模板函数,用于将一个迭代器移动给定距离。本条款讲述了如何利用C++和编译器特性实现std::advance,其中最核心的问题便是如何在编译器得到一个类的类型信息。原创 2023-01-17 23:48:41 · 465 阅读 · 0 评论 -
C++-Pimpl编程技巧
“Pointer to implementation”(pimpl)是一种C++编程技巧,例子:其主要思想是将一个类的私有数据成员和私有成员函数放入一个单独的实现类中。该技巧的好处:二进制兼容。增减私有数据成员,私有成员函数、参数等不影响库的二进制接口,只需重新编译库,不需要重新编译使用该库的代码。隐藏了类实现。如代码所示,这里的"类实现"指的是widget类实现,只能看到指针impl,通过前向声明,甚至可以不需要include其头文件,类使用者无从知道impl的实现细节。减少了依赖。如代码所示,如果使用原创 2022-06-17 09:06:18 · 204 阅读 · 0 评论 -
Qt-Q_OBJECT宏及控件提升导致的类重定义问题
在项目中遇到了这么个奇怪的问题,类加上Q_OBJECT宏之后,出现类重定义报错。具体描述如下:SelectConvertDialog是一个ui类,.ui文件中通过控件提升的方式提升QTableWidget为SelectConvertTable,而SelectConvertTable类头文件中也加上了Q_OBJECT宏,编译后报错:重定义意味着出现了两次声明,但是我们显然只声明了一次,那么唯一的可能,就是在头文件include的时候,将这个头文件include了两次报错的文件是mocs_compilatio原创 2022-06-14 10:13:20 · 976 阅读 · 0 评论 -
C++-Nuget包一键打包-上传工具开发分享
前言网上找了写打包工具,感觉都不太好用,于是决定自己开发一个Nuget包工具。使用说明为了实现方便起见,使用软件前有部分约定需要遵守,否则无法正确使用该工具:应配置好环境变量,使得能在命令行中直接调用nuget和devenv.com项目生成dll或者lib项目目录下应包含一个include文件夹,包含所有dll或lib对外提供的头文件,目录结构可嵌套版本号由数字+'.'组合,通常应为x.x.x或者x.x.x.x正常的使用流程为:选择解决方案文件项目名称、ID、版本号会自动填写手动原创 2022-05-26 15:00:31 · 1747 阅读 · 0 评论 -
VTK-TextAnotation2D和vtkVectorText
TextAnotation2D是显示在三维物体之上的一个平面内(overlay plane)。而vtkVectorText文字本身是三维数据,跟其他三维物体没有区别。vtkFollower是一种Actor,它总是朝向renderer的相机。TextAnotation2D#include "TextAnotation2D.h"#include "vtkSphereSource.h"#include "vtkPolyDataMapper.h"#include "vtkLODProp3D.h"#inc原创 2022-05-05 11:45:14 · 439 阅读 · 0 评论 -
C++-链式调用const成员函数
假设定义了一个类A,A包含一个int类型的数据成员n、print成员函数和set成员函数,print成员函数打印n值,set成员函数改变n值。由于print不会改变数据成员,因此应声明为const成员,另外又因为是const成员,所以隐式传入的this指针是const A *类型,返回引用是为了方便链式调用,此时*this是const A 类型,所以返回值是const A &类型,代码如下:class A { int i = 0;public: const A &print()原创 2021-03-07 20:50:29 · 342 阅读 · 0 评论 -
C++-bind基本用法和作用
文章目录bind是什么bind怎么用bind作用bind绑定引用参数bind是什么bind是一个标准库函数,定义在functional头文件中。可以将bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成新的可调用对象来适应原对象的参数列表。bind怎么用调用bind的一般形式为:auto newCallable=bind(callable,arg_list);newCallable和callable都是可调用对象,arg_list对应calllable的参数。当我们调用newCal原创 2021-10-26 23:15:35 · 5441 阅读 · 0 评论 -
C++-左值和右值
文章目录左值和右值什么是表达式左值和右值函数返回左值和右值左值到右值的转换左值引用常量左值引用左值和右值什么是表达式表达式由一个或多个运算对象(operand)组成,对表达式求值得到一个结果(result),字面值和变量是最简单的表达式,其结果就是字面值和变量的值。运算符(operator)和运算对象组合可以生成复杂的表达式。左值和右值C++的表达式的结果要么是左值(lvalue),要么是右值(rvalue):左值指向一个特定的内存位置右值不指向特定的内存位置通常来说右值是临时的和短暂的,原创 2021-10-07 17:15:07 · 452 阅读 · 0 评论 -
C++-直接初始化和拷贝初始化
文章目录初始化拷贝初始化直接初始化构造函数与拷贝构造函数拷贝初始化与拷贝构造函数例子初始化变量的初始化有两种方式:直接初始化(direct initialization)拷贝初始化(copy initialization)拷贝初始化如果使用等号(=)初始化一个变量,则执行的是拷贝初始化。直接初始化不使用等号的,则是直接初始化。构造函数与拷贝构造函数如果一个构造函数的第一个参数是自身类型的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数拷贝初始化与拷贝构造函数拷贝初始化依原创 2021-10-05 21:46:42 · 983 阅读 · 0 评论 -
C++-右值引用和移动语义
文章目录右值引用和移动语义右值引用移动语义实现拷贝构造函数实现拷贝赋值函数类设计的局限性使用右值引用实现移动语义实现移动构造函数实现移动赋值函数何时使用移动语义其他移动构造函数不会被调用?如果 RVO 默认执行优化工作,我为什么要关心实现移动语义?我们在Holder示例中做了 RAII标记移动构造函数和移动赋值运算符为noexcept使用copy-and-swap进一步优化和增强异常安全性完美转发(forwarding)右值引用和移动语义右值引用在 C++ 中,存在一些临时、生存期短的值,它们无法以任翻译 2021-10-07 21:17:16 · 1014 阅读 · 0 评论 -
C++-内联函数
内联函数将频繁的小操作定义函数有以下好处:理解有意义的函数名比读懂等价的表达式要容易使用函数确保行为的统一,每次操作都按照同样的方式运行修改函数比修改所有表达式出现的地方要简单函数可重复利用但是函数调用有额外开销。使用内联函数可以避免这些额外的开销,在函数定义处加上inline关键字即可将函数声明为内联的inline bool isGreater(int a,int b){ return a>b;}在编译过程中,内联函数会在调用处展开,如:int ret=isGre原创 2021-10-30 21:05:26 · 94 阅读 · 0 评论 -
C++-1分钟学会lambda
lambdalambda表达式是可调用对象的一种对一个对象或者表达式,如果可以对其使用调用运算符,则称它是可调用对象。可调用对象有四种:1.函数2.函数指针3.重载了调用运算符的类4.lambda表达式lambda表达式形式[capture list](parameter list) ->return type{function body}必须使用尾置返回来指定返回类型,可以忽略参数列表和返回类型lambda内可以使用外部的变量,值捕获方式:[var1,var2](){原创 2021-10-24 20:12:03 · 93 阅读 · 0 评论 -
C++-标准库类型function介绍
文章目录可调用对象和调用形式函数表的例子function救场重载函数二义性问题可调用对象和调用形式C++中有几种可调用对象:1.函数2.函数指针3.重载了调用运算符的类4.lambda表达式5.bind创建的对象可调用对象有不同的类型,每个lambda有唯一的类类型,函数和函数指针的类型由参数和返回值决定。不同类型的可调用对象可能有相同的调用形式,调用形式表明了调用返回的类型和传递给调用的实参类型,一种调用形式对应一个函数类型。如:int(int,int)是一个函数类型,它接受两原创 2021-10-30 19:39:05 · 1668 阅读 · 0 评论 -
C++-函数和函数指针
文章目录函数和函数指针使用函数指针函数指针形参简化函数指针类型声明如何理解复杂的指针类型声明函数和函数指针函数和函数指针是不同的,函数指针指向的是函数而非对象,和其他指针一样,函数指针指向某种特定的类型,函数的类型由它的返回类型和形参共同决定(换句话说一种调用形式对应一个函数类型),与函数名无关。声明一个函数:bool add(int a,int b);声明一个函数指针,只要用指针替换函数名即可:bool (*pf)(int a,int b);*fp两边的括号是必须的,否则会变成声明一个函原创 2021-10-31 11:53:19 · 275 阅读 · 0 评论 -
C++-swap
交换操作swap操作交换两个相同类型容器的内容。vector<string> vec1(10);vector<string> vec2(24);swap(vec1,vec2);调用swap后,vec2有10个string元素,vec1有24个string元素。除array类型外,交换两个容器内容的操作保证会很快,因为swap只是交换了两个容器的内部数据结构,元素本身并未交换,swap可以保证在常数时间内完成。元素不会被移动意味着,除string外,指向容器的迭代器、引用原创 2021-11-05 22:10:32 · 4242 阅读 · 0 评论 -
C++-noexcept
noexceptC++11引入的关键字,用于告诉编译器该函数不会发生异常,有利于编译器优化通常在编写移动构造函数和移动拷贝函数的时候使用。个人理解这是因为这些函数中只是进行普通的变量赋值操作,而没有分配空间、调用其他函数、指针解引用等操作,所以可以认为这些函数一定不会发生异常。例如,我们在vs中编写移动构造/拷贝函数的时候,会提示将其声明为noexcept。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N6dP6uR0-1635948904135)(vx_images原创 2021-11-03 22:15:24 · 1218 阅读 · 0 评论 -
C++-异常处理
异常处理C++中异常处理包括:throw表达式,用于引发异常,表明遇到了无法处理的问题try语句块,try语句块开始,后接多个catch语句,用于处理特定的异常异常类,用于throw表达式和相关catch之间传递异常信息throw表达式if(condition){ throw runtime_error("Error1");}runtime_error是一个异常类,抛出异常将终止当前函数,并从内层向外寻找能处理该异常的代码。如果找不到将执行标准库函数terminate,导致程原创 2021-10-31 22:08:27 · 276 阅读 · 0 评论 -
C++-各种回调函数和相关参数写法
回调函数给一个函数传递一个函数指针,在该函数中调用该指针指向的函数,这个被调用的函数称为回调函数。在学习了可调用对象的概念以后,我们可以传入各种各样的可调用对象,来实现回调功能。直接上代码class TestClass{public: int add(int a, int b) { return a + b; }//public成员函数};class TestClass2{public: static int add(int a, int b) { return a + b; }/原创 2021-11-03 23:58:00 · 2620 阅读 · 0 评论 -
C++-模板基础和函数模板
文章目录模板模板定义模板一个模板就是创建类或者函数的蓝图或者公式,我们提供足够的信息,编译器在编译时将蓝图转换为特定的类或者函数模板定义模板定义以关键字template开始,后跟一个模板参数列表,模板参数之间用逗号分隔,模板参数列表用尖括号括起来,如一个函数模板定义如下:template <typename T>bool func(const T& v1,const T& v2){ return v1<v2;}模板参数表示在类或者函数定义中用到的原创 2021-11-15 21:35:15 · 771 阅读 · 0 评论 -
C++-universal references、引用折叠与完美转发
universal referenceIf a variable or parameter is declared to have type T&& for some deduced type T, that variable or parameter is a universal reference.如果一个变量或参数声明为T&&类型,且T为推导类型,则这个变量或者参数称为universal reference。如果被一个左值初始化,它就是一个左值;如果它被一个右值原创 2022-02-15 18:22:57 · 615 阅读 · 0 评论 -
C++-dllmain介绍
dllmain百度解释的很清楚跟exe有个main或者WinMain入口函数一样,DLL也有一个入口函数,就是DllMain,对于动态链接库,DllMain是一个可选的入口函数入口函数定义BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, // 指向自身的句柄 _In_ DWORD fdwReason, // 调用原因 _In_ LPVOID lpvReserved // 隐式加载和显式加载);系统在调用LoadLibrary和Fre原创 2022-01-05 15:46:34 · 2812 阅读 · 0 评论 -
C++-正确地循环删除std::map
假设我们有一个map:map<int, int> mp;mp.insert(make_pair(1, 1));mp.insert(make_pair(2, 2));mp.insert(make_pair(3, 3));现在我们要删除掉这个map里的所有元素,先看一种错误写法:auto it = mp.begin();while (it != mp.end()){ mp.erase(it); it++;}错误的原因是erase方法调用后会使迭代器it失效,此原创 2022-02-15 10:18:16 · 4742 阅读 · 0 评论 -
C++-dllexport与dllimport介绍和使用
dllexport与dllimportdllexport与dllimport存储级属性是微软对C和C++的扩展,可用于从dll中导入或导出函数、数据、对象(objects)语法__declspec( dllimport ) declarator__declspec( dllexport ) declarator这些属性显式地定义了dll提供给客户端的接口,客户端可以是一个可执行文件或者另一个dll。dllexport声明的使用免去了模块定义(.def)文件的使用,def文件至少包含相关导出函数的原创 2022-01-05 15:47:59 · 12421 阅读 · 0 评论 -
C++-可变参数与可变参数模板
可变参数与可变参数模板可变参数三个点...表示可变参数列表,必须放在函数所有参数的最后面。函数至少要有一个固定参数(即使这个参数只是占位作用),否则无法获取可变参数列表中的每个参数。C++中...前的逗号是可选的,C是强制的。作为可变参数传递时,可能会发生类型提升,如char类型转化为int,float类型转化为double,类型提升详见这里和这里。通过<stdarg.h>中的几个宏可以获取可变参数列表中的每个参数:va_start。允许访问可变参数列表va_arg。访问下一个可变原创 2022-01-08 15:29:53 · 689 阅读 · 0 评论 -
C++-dll动态加载与卸载(LoadLibraryEx与FreeLibrary)
dll动态加载与卸载这里的动态加载指的是:程序编译时不需要任何dll相应的lib进行链接,程序本身通过相关函数加载和卸载dll,并使用其中的函数。代码如下:class PluginManager{public: static bool loadPlugin(const QString& pluginPath, PluginInstanceInfo& pluginInfo); static bool freePlugin(PluginInstanceInfo&原创 2022-01-05 15:50:03 · 6833 阅读 · 0 评论