
C/C++
文章平均质量分 54
萧戈
从事视频方向的开发
展开
-
深入理解std::shared_ptr:原理、用法及其线程安全性
是 C++ 标准库中的一种智能指针,允许多个指针共享管理同一个对象的生命周期。它通过引用计数(reference count)来记录有多少个指针指向同一个对象,当引用计数为零时,会自动释放对象,避免手动管理内存带来的风险。// p1 引用计数为 1// p1 和 p2 都指向同一个 int,引用计数为 2// 输出 10p2.reset();// p2 被重置,引用计数减少为 1} // 作用域结束,p1 被销毁,引用计数为 0,对象被释放在上面的例子中,转载 2025-02-10 14:38:31 · 259 阅读 · 0 评论 -
半精度浮点数在计算机中的表示方式
半精度浮点数(Half-precision floating-point)是一种计算机数学中使用的浮点数表示方法。在IEEE 754-2008标准中,半精度浮点数被定义为使用16位(即2字节)来表示。这种16位的表示方式在存储空间有限或处理速度要求较高的场景下非常有用,但其表达的数值范围和精度相比于单精度(32位)和双精度(64位)浮点数要小得多。其中,�S是符号位,�E是指数部分(考虑偏移),�M是尾数部分,表示为1加上二进制小数。原创 2024-02-29 15:10:07 · 1593 阅读 · 0 评论 -
fopen/fwrite/fread 对UNICODE字符写入的总结
从上面截图可知,数据确实成功写入了,文件也是UNICODE编码格式,但是写入的字符集不是UNICODE编码的,所以记事本打开会出现乱码。如果我们将写入的字节流改为char类型的数据,编码格式和字节流就能对应上,都为ANSI,此时文件显示也没问题。从截图可知,写入文件的编码格式为UNICODE编码,UNICODE编码格式的文件前面有2个字节的文件头。从截图可知,确实是将Unicode字符集转成了UTF-8编码格式的字符集,然后写入了文件。模式打开文件时,进行读写操作的数据应为 UTF-16 编码,存储为。原创 2023-11-18 19:40:29 · 2309 阅读 · 0 评论 -
longlong/int64_t/uint64_t数据类型格式化输出(转成字符串)
在 C++ 中,int64_t是一个 64 位整型,通常用于确保整数大小在各种平台上的一致性。要格式化输出int64_t类型的变量,您可以使用printf函数或 C++ 的流输出。原创 2023-11-13 17:33:23 · 6984 阅读 · 0 评论 -
C++ #pragma 预处理指令
因为DLL中的全局数据对于每一个调用它的进程而言,是私有的,不能共享的。#pragma pack规定的对齐长度,实际使用的规则是: 结构,联合,或者类的数据成员,第一个放在偏移为0的地方,以后每个数据成员的对齐,按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。使用示例,假如在程序中我们定义了很多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的时候就进行检查。也就是说,在DLL中定义一个共享的有名字的数据段。转载 2023-05-08 17:15:40 · 933 阅读 · 1 评论 -
链接静态库时pdb如何处理?
我又编译了另外一个动态库,名称为:RenderEngine3D.dll。pdb文件为:RenderEngine3D.pdb。此dll依赖于JXEngine.lib,我在生成此dll的时候,需要将JXEngine.lib库文件拷贝到对应的目录下面,此时dll才能链接到,但是不需要拷贝JXEngine.pdb文件(可能是JXEngine.lib文件里面记录的有pdb文件的路径)。我编译了一个静态库名称为:JXEngine.lib,生成的pdb为:JXEngine.pdb.原创 2023-05-05 14:15:28 · 360 阅读 · 0 评论 -
C语言运算符优先级和结合性一览表
所谓优先级就是当一个表达式中有多个运算符时,先计算谁,后计算谁。这个其实我们在小学学算术的时候就学过,如1+4÷2。但是C语言中的运算符已经远不止四则运算中的加减乘除了,还有其他很多运算符。当它们出现在同一个表达式中时先计算谁后计算谁呢?所以本节还是有必要讲一下的。最后我还会将所有运算符展示出来,然后告诉你哪个优先级高、哪个优先级低。首先不需要专门记忆,也没有必要。因为作为初学者,哪个优先级高、哪个优先级低我们很难记住。就算死记硬背记住了,时间长不用也会忘记。转载 2023-04-07 10:03:10 · 552 阅读 · 0 评论 -
C++定义能灵活表示多维空间中的点
我们经常需要定义一个类来表示一个2维或者3维空间中的点,并且类里面的数据类型也是不固定的。当我们需要一个表示2维空间中的类的时候,只需要用Point表示就可以。当我们需要一个表示3位空间中的类的时候,只需要用Point表示就可以。并且类里面的数据类型也是可以任意修改的。原创 2023-03-18 10:52:48 · 240 阅读 · 0 评论 -
c++类对象数据成员和虚函数的内存布局
pB的值-pC的值=12字节:这是因为类C的继承关系中,类A是第一个基类,类B是第二个基类,所以在类C对象的内存布局中,类B放在类A的后面,只要把pC的地址加上类A占用的部分(12字节,对齐到4字节)就是pB的地址。类C对象占用的内存大小为40字节:类A的部分占用16字节+类B的部分占用16字节+数据成员c占用4个字节,此时只有36个字节,根据字节对齐默认为8字节,所以最终加上字节对齐,整个类C占用的内存大小为40字节。派生类C中包含了2个虚表,一个虚表是指向基类A中的函数,一个虚表是指向基类B中的函数。原创 2023-02-24 11:27:46 · 682 阅读 · 0 评论 -
VC静态库的调试
综上所述,想要调试静态库只要保持静态库的pdb文件位置不变或者将静态库的pdb文件和静态库lib文件放在一起,然后正常链接。调试信息就被包含到了最终生成的文件的pdb文件里,需要调试的时候直接加载最终生成的文件的pdb文件,和正常调试动态库或者可执行文件一样。没关系,链接器链接的时候如果找不到绝对路径的pdb文件还会搜索和静态库lib文件放在一起的和原pdb文件同名的pdb文件。的确如此,链接器在连接的过程中会将静态库的pdb文件中被用到的调试信息解析出来然后合并到最终的生成文件的pdb文件里。转载 2022-11-15 09:55:14 · 791 阅读 · 0 评论 -
#progma pack(x)说明
sh占2个Byte,它的对齐模数是2(2转载 2022-11-10 16:05:59 · 251 阅读 · 0 评论 -
通过位运行代替乘除求余运算
一个数对2,4,8,16...等数求余,可以通过&运算符实现(比例:对2求余,可以表示为 某个数&1)一个数乘以2可以通过向左位移1位。一个数除以2可以通过向右位移1位。原创 2022-08-31 09:27:44 · 250 阅读 · 0 评论 -
MinGW 安装及使用方面的文章总结
MinGW-w64 C/C++编译器下载和安装的方法步骤(入门教程)win下使用MinGW-w64+cmake搭建c++开发环境_丰色木夕的博客-优快云博客原创 2022-07-08 14:52:40 · 316 阅读 · 0 评论 -
c++中operator()的用法简单理解记录
c++ 中的operator()有两大主要作用:Overloading------重载()操作符; Casting------实现对象类型转化。一. 重载()操作符函数对象:定义了调用操作符()的类对象。当用该对象调用()操作符时,其表现形式如同普通函数一致,因此取名为函数对象。与普通函数相比,函数对象更加灵活,代码看上去更加优雅。函数对象有自己的状态。可以在类中定义状态变量,这样一个函数对象在多次的调用中可以共享这个状态; 函数对象有自己特有的类型。可以传递相应的类型作为参数来实例化相应转载 2022-05-10 15:18:58 · 12440 阅读 · 0 评论 -
c++使用模板代替一个函数声明
正常的函数声明代码如下:typedef int (*add_type)(int a,int b);int process_data(add_type add,int a,int b){ return add(a,b);}这样是需要写一个函数类型声明的,感觉比较麻烦,可以用模板简化函数声明。代码如下:template<typename Function>int process_data(Function add,int a,int b){ return原创 2022-04-21 12:02:32 · 1014 阅读 · 0 评论 -
C++ 中sort排序改变数值相同的数据相对位置的解决办法
今天给大家介绍个超级好用的知识:写了那么多的排序,但是其实C++里封装有排序函数,而且功能非常强大。sort函数有sort(),stable_sort()和partial_sort()。sort()函数是对给定区间的元素进行排序,但是会改变值相同的元素的相对位置。stable_sort()是对给定区间的元素进行稳定排序,如果两个元素相等,那么排序完成后两个元素的相对位置保持不变,partial_sort()是对给定区间的元素进行部分排序。默认的顺序是由小到大进行排序。三种函数的用法如下v为容转载 2021-12-15 19:37:41 · 3177 阅读 · 1 评论 -
float类型的存储方式
在c语言中float函数是单精度的。它在内存中以二进制的形式存储。分为符号位,阶码与尾数三部分。符号位最为简单,如果你存储的是正数那么符号数就是0。如果是负数,则为1。下面,我以13.625为例说明阶码与尾数的表示方法。首先,我们取出13.625的整数部为13。对其使用短除法(对该数除以2,直至不能再除的一种方法)结果如下将各余数自下而上排列,则得到了13的二进制表示。之后,取出13.625的小数部分为0.625对其每次乘2取出整数留下小数,直至得到1。结果如下自上而下将取出的整数排转载 2021-05-11 10:58:49 · 3942 阅读 · 0 评论 -
Static全局变量和Static全局方法
1、static全局变量与普通的全局变量有什么区别?(全局方法类似)答:全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限.原创 2021-01-14 11:21:12 · 440 阅读 · 0 评论 -
C++虚函数表解析(图文并茂,非常清楚)( 任何妄图使用父类指针想调用子类中的未覆盖父类的成员函数的行为都会被编译器视为非法)good
C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。虚函数表 对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简...转载 2020-12-25 09:40:09 · 801 阅读 · 0 评论 -
C++对象模型:单继承,多继承,虚继承,菱形虚继承,及其内存布局图
C++目前使用的对象模型:此模型下,nonstatic数据成员被置于每一个类的对象中,而static数据成员则被置于类对象之外,static和nonstatic函数也都放在类对象之外(通过函数指针指向),而对于virtual函数,则通过虚函数表+虚函数指针来支持:1)每个类生成一个表格,称为虚表(virtual table,简称vtbl),虚函数表中存在一堆指针,这些指针指向该类的每一个虚...转载 2019-11-26 17:02:04 · 565 阅读 · 1 评论 -
Assert宏
#ifndef Assert#if defined( DEBUG ) || defined( _DEBUG )#define Assert(b) do {if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}} while(0)#else#define Assert(b)#endif //DEBUG || _DEBUG#endif...原创 2019-04-19 09:51:42 · 233 阅读 · 0 评论 -
C++ - 判断文件夹(folder)是否存在(exist)
判断文件夹(folder)是否存在(exit)本文地址: http://blog.youkuaiyun.com/caroline_wendy/article/details/21734915写入程序, 需要在文件夹中写入数据, 如果文件夹不存在, 则无法写入, 在程序入口需要判断;由于属于系统层, Windows的两种解决方法.参考: http://stackoverflow.com/que...转载 2019-01-17 11:26:50 · 5720 阅读 · 0 评论 -
判断文件、目录是否存在:C、C++、Windows API、 boost
一、判断文件是否存在#ifdef WIN32#include <io.h> //C (Windows) access#else#include <unistd.h> //C (Linux) access #endif #include <fstream&g...转载 2019-01-17 11:20:55 · 4881 阅读 · 0 评论 -
文件完整路径去掉文件名得到路径部分
wchar_t drive[_MAX_DRIVE]; wchar_t dir[_MAX_DIR]; _wsplitpath(sOutImagePath, drive, dir,NULL, NULL); wchar_t newPath[_MAX_PATH] = { 0 }; _wmakepath(newPath, drive, dir, NULL, NULL); DWORD ftyp ...原创 2019-01-17 11:18:36 · 3512 阅读 · 0 评论 -
普通字符和宽字符之间转换函数
以下函数会在内部分配内存,需要调用程序调用delete释放内存:namespace _com_util { // Convert char * to BSTR // BSTR __stdcall ConvertStringToBSTR(const char* pSrc) ; // Convert BSTR to char * // char*...原创 2018-10-19 10:50:42 · 849 阅读 · 0 评论 -
我的第一个COM组件
资源地址:COM组件和测试代码原创 2018-06-23 22:44:45 · 286 阅读 · 0 评论 -
聊聊c++ dll的函数导出和加载
C++ DLL导出函数有两种方式(__declspec(dllexport)和.def文件)。c++加载DLL也有两种方式(静态链接和动态链接)。下面这4点分别进行讨论。一.用__declspec(dllexport)导出函数:例:extern "C" __declspec(dllexport) int __stdcall add(int a, int b){ return a + b;}导出的D...原创 2018-06-23 12:25:37 · 10048 阅读 · 0 评论 -
智能指针类的实现
template<class T,const IID* piid>class IPtr{public: IPtr(){m_pI=NULL;} IPtr(T* lp) { m_pI=lp; if(m_pI) m_pI->AddRef(); } IPtr(IUnknown* pI) { m_pI=NULL;...原创 2018-06-22 12:28:42 · 245 阅读 · 0 评论 -
派生类和基类的转换
一.概述 派生类和基类之间的转换有3中方式:a.默认的强转,如 A *pa=(A*) p;b.dynamic_cast转换,A *pa=dynamic_cast<A*>(p);c.static_cast转换,A *pa=static_cast<A*>(p);还有一种强制转换为 reinterpret_cast,这种转换不会改变地址。二代码实例:class A{publi...原创 2018-06-19 10:43:29 · 1633 阅读 · 0 评论 -
异步执行如何在一个函数中实现
前言:异步执行经常要用到2个函数,一个函数处理UI线程的调用,另外一个函数处理内核线程调用。并且中间要用很多命令来转接不同的函数。这样函数的代码量和处理要麻烦很多。可以用模板函数做一下转接。模板函数如下:#pragma once#include "stdafx.h"#include <stdio.h>#include <iostream>#include <...原创 2018-06-01 16:57:10 · 1386 阅读 · 0 评论 -
std::list 的使用
使用标准的std::list进行容器数据处理时,操作比较底层。我们可以,减少引用标准MFC标准库,减少系统的大小,但同时也存在有不方便的操作之处,这里同大家分享一些使用心得...... 在使用std::list::iterator链表遍历器进行访问list STL 中的list 就是一 双向链表,可高效地进行插入删除元素。list不支持随机访问。转载 2017-10-18 16:28:02 · 2685 阅读 · 0 评论 -
C++宽字符处理函数 与 普通函数 对照表
字符分类: 宽字符函数 普通C 函数描述iswalnum() isalnum() 测试字符是否为数字或字母 iswalpha() isalpha() 测试字符是否是字母iswcntrl() iscntrl() 测试字符是否是控制符i转载 2017-10-17 14:20:52 · 699 阅读 · 0 评论 -
MultiByteToWideChar和WideCharToMultiByte用法详解
今天写ini文件的时候发现的问题: TCHAR temp[128]; //strcpy_s(temp, request.newVersion); MultiByteToWideChar(CP_ACP, 0, request.newVersion, -1, temp, 100); WritePrivateP转载 2017-10-17 14:18:44 · 2333 阅读 · 0 评论 -
Win7/Win10以管理员权限注册控件批处理文件
@echo offREM ________________________________________________________________SET "SELFPATH=%~dp0">nul 2>&1 "%SYSTEMROOT%\system32\regSvr32.exe" "%SELFPATH%XXX.dll"if '%errorlevel%' NEQ '0'原创 2017-09-14 12:44:20 · 2282 阅读 · 0 评论 -
int (*p)[10] 和 int *p[10]的区别
第一:char (*p)[10] 主要用在函数的参数上面,主要用于约束参数数组的长度。int add(int (*p)[2])//表示必须输入2个元素的int数组{return (*p)[0]+(*p)[1];}void main(){int a[2];a[0]=1;a[1]=2;printf(“%d\n”,&a);return;}第二:原创 2017-09-08 19:24:16 · 4261 阅读 · 0 评论 -
c++中的隐藏、重载、覆盖(多态)
1 重载与覆盖 成员函数被重载的特征:(1)相同的范围(在同一个类中);(2)函数名字相同;(3)参数不同;(4)virtual关键字可有可无。 覆盖是指派生类函数覆盖基类函数,特征是:(1)不同的范围(分别位于派生类与基类);(2)函数名字相同;(3)参数相同;(4)基类函数必须有virtua原创 2017-07-16 13:15:47 · 282 阅读 · 0 评论 -
C++反射
注意cpp文件生成的顺序C++反射机制的实现 .前几天用C++为《捕鱼达人》移植UI编辑器的时候,遇到了几个难点。一个是通过类名的字符串创建相应的类的实例化。还有一个是通过属性的名字字符串来操作相应的类的属性。用支持反射的Objective-C或者Java语言来实现类似功能是非常简单的。但是C++不支持,纠结了几天,终于实现了类似于反射的功能。思路分为以下几步:1、在要原创 2017-05-16 15:18:37 · 361 阅读 · 0 评论 -
简单工厂组合策略模式_反射
#include #include using namespace std;typedef void* (*CreateClass)(int,int);#define DECLARE_CLASS(className)\ static CKDynamicClass *className##dc;#define IMPLEMENT_CLASS(c,className)\ CKDy原创 2017-05-16 15:18:02 · 450 阅读 · 0 评论 -
如何正确使用C++多重继承
C++多重继承一直是一个让人搞不太清楚的一个问题,但是有时候为了实现多个接口,多重继承是基本不可避免,当然在Windows下我们有强大的COM来帮我们搞定这个事情,不过如果你想自己实现一套类似于COM的东西出来的时候,麻烦事情就来了。在COM里面,有两个很基础的,而且我们都会用到的特性:纯虚接口:一般使用一个只有纯虚函数的类来作为接口引用计数:在C++中一般都使用引用计数来管理转载 2017-05-10 13:59:04 · 2608 阅读 · 1 评论 -
Unicode(UTF16)、UTF8、ansi编码格式字符串之间相互转换
C++标准模板库只能实现宽字符和utf8编码格式字符串之间的转换,而且这个功能在c++11引入,在C++17中废弃,所以不建议使用,如果需要跨平台,建议使用 ICU(International Components for Unicode)库。C++ 标准库没有直接提供 ANSI 和 UTF-8 之间的转换功能,但你可以使用第三方库,例如 ICU(International Components for Unicode),或者在 Windows 平台上使用特定的 API 进行转换。原创 2016-12-21 16:12:02 · 15489 阅读 · 0 评论