
c++
文章平均质量分 65
宇龍_
有些白嫖党连个赞都不点甚至直接抄走了说原创,新发布的都写到专栏里吧,哎。
私聊给群号,可进Q群咨询问题。
展开
-
由联合体union引出的大小端问题
由联合体union;大小端问题原创 2022-08-07 05:00:00 · 221 阅读 · 0 评论 -
C++类型重载
C++中的类型重载很好用,甚至可以基于类型重载新发明一种新的编程语言。下面简单写个demo来展示类型重载,如果要自己写个好用的类,还需要重载等号等运算符。class CTest{public: operator int() { return 1; } operator bool() { return false; } operator std::string() { return "ffff"; }};int main(){ CTest test; i原创 2022-05-19 21:38:06 · 658 阅读 · 0 评论 -
CString在多线程中的问题
闲来没事,聊聊CString在多线程中很容易踩的坑,这个坑很可能存在于你现在的项目中。举例:int main(){ CString str = L"test"; CString strThread1 = str; CString strThread2 = str; //将两个参数传递到各自的线程中,以下使用伪代码 CThread thread1(strThread1); CThread thread2(strThread2); thread1.wait();原创 2022-05-17 22:28:46 · 608 阅读 · 11 评论 -
子类隐藏父类的同名函数
在C++中,子类是不能重载父类函数的,因为重载只发生在同一个类中。所以在不考虑虚函数重写的情况下,子类中所有的同名函数(仅仅是与父类的函数名称相同),都会导致父类的同名函数被隐藏。见代码:#include <stdio.h>#include <stdlib.h>class CFather{public: void Test() { Print(); } void Print() { printf("CFather\n"); }};cl原创 2022-04-16 11:13:19 · 1045 阅读 · 0 评论 -
C++条件变量中的notify_one()和notify_all()区别
多个线程在调用条件变量的wait方法时会阻塞住notify_one:此时调用notify_one会随机唤醒一个阻塞的线程,而其余的线程将仍然处于阻塞状态,等待下一次唤醒。notify_all:调用notify_all则会唤醒所有线程,线程会争抢锁,当然只有一个线程会获得到锁,而其余未获得锁的线程也将不再阻塞,而是进入到类似轮询的状态,等待锁资源释放后再去争抢。假如同时有10个线程阻塞在wait方法上,则需要调用10次notify_one,而仅仅只需要调用1次notify_all...原创 2022-01-13 17:17:31 · 3089 阅读 · 0 评论 -
C/C++实现关闭命令行快速编辑模式(Windows系统)
背景:开发了一个程序,需要通过cmd命令行来运行该程序,但在多次使用后发现,有时候程序会卡住,必须要按回车程序才会输出,网上搜索了一番,发现这是由于命令行窗口的快速编辑模式导致的,我希望能在调用我的程序时,该模式就被关掉,而不是让用户手动关闭。方案:在主函数开头加入几行代码即可:HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);DWORD mode;GetConsoleMode(hStdin, &mode);mode &=原创 2022-01-12 15:41:05 · 1997 阅读 · 1 评论 -
C++获取CPU核心数(用来初始化线程池)
std::thread::hardware_concurrency()该函数返回CPU核心的数量,当系统无法获取时,函数返回0#include <thread>unsigned int nCpu = std::max(std::thread::hardware_concurrency(),(unsigned int)1);原创 2022-01-12 15:37:04 · 2100 阅读 · 1 评论 -
mysql_ping阻塞的问题
在我实现的数据库连接池中有这样一个逻辑:从数据库连接池中获取到现成的空闲连接后,需要使用mysql_ping检测该连接是否可用,若该连接可用则直接返回,否则的话就释放该资源并重新创建一个新的数据库连接。出现问题:但在实际使用过程中出现了一个问题,在连接池中创建空闲连接大约5分钟后,使用mysql_ping检测连接情况的时候,该API会阻塞大约20分钟(这种阻塞的情况在某些服务器上又不存在)解决办法:1、创建数据库连接时设置MYSQL_OPT_RECONNECT(经测试,无法解决该原创 2021-12-07 11:16:42 · 1220 阅读 · 0 评论 -
yhirose服务器端发送文件
yhirose是c++开源的http库(github地址:https://github.com/yhirose/cpp-httplib),最近结合Qt用了一段时间,简直不要太好用。下面是应用到的发送文件的场景:httplib::Server svr;QByteArray btArr;svr.Get("/file", [&](const httplib::Request &, httplib::Response &res) { QFile file("E:/test.ex原创 2021-01-28 11:26:22 · 292 阅读 · 0 评论 -
Qt生成dump文件并调试
1、编译时生成pdb文件:在.pro文件中加两行配置QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFOQMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO然后重新编译,即可在exe文件的目录下生成.pdb文件。2、项目中增加崩溃时生成dump文件的代码#include <tchar.h>#include <Windows..原创 2020-09-21 13:47:52 · 2680 阅读 · 3 评论 -
C++踩坑记录
维护别人写的代码,代码如下:std::unique_ptr<Test> test(new Test); //1 实际项目中并不是使用的stl中的智能指针,是别人封装的,而且我这里没有源码test->connect(); //2代码运行正常,由于代码调整,我注释了第二行,运行报错。。。。一度怀疑智能指针的代码有问题,却苦于没有源码。。最后在在Test类中看到这一幕:Test(){}~Test{ if(NULL !=原创 2020-06-04 14:28:04 · 248 阅读 · 0 评论 -
C++单例类的内存自动回收
就是利用类静态成员在程序运行结束后会自动释放的原理,在其析构函数中释放其管理的内存。直接贴代码:#include "stdafx.h"#include <stdio.h> class Test{public: static Test&GetInstance() { if(NULL == m_pInstance) m_pInstance = new Test; return *m_pInstance; }private: static Test原创 2020-05-29 10:01:56 · 705 阅读 · 0 评论 -
C++智能指针
什么是智能指针?智能指针的原理:将基本类型指针封装为类对象指针(这个类肯定是个模板,以适应不同基本类型的需求),并在析构函数里编写delete语句删除指针指向的内存空间。智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放,智能指针就是一种栈上创建的对象,函数退出时会调用其析构函数,这个析构函数里......原创 2020-03-26 11:21:37 · 335 阅读 · 0 评论 -
C++编译原理-彻底解决链接错误
前言:在开发项目的时候会经常性的出现各种各样的链接错误。究其原因是因为对C++的编译过程不理解所致。当深入理解了整个编译的过程,那么所有的问题将迎刃而解。要点:1、头文件中使用 #pragma once //vs一般自动生成//test.h#pragma once//接下来是头文件的内容2、头文件中使用条件编译#ifndef.......#define.......原创 2019-10-20 22:48:54 · 9194 阅读 · 0 评论 -
SendMessage导致的死锁问题
前言:试想这样一种场景:子线程通过SendMessage同步消息到主线程,假设子线程的结束是通过标志位来控制的。当主线程想要尝试结束子线程的时候一般是这样操作的,bFlag = false;WaitForSingleObject(hThread,INFINITE); //阻塞等待CloseHandle(hThread);将标志位置为false后,在子线程的主循环中肯定会判...原创 2019-09-28 20:33:54 · 11167 阅读 · 0 评论 -
MFC窗口实现最小化到托盘
以下为实现代码#define WM_SHOWTASK (WM_USER +1)//消息映射BEGIN_MESSAGE_MAP(Test, CDialog) ON_MESSAGE(WM_SHOWTASK,&Test::OnShowTask)END_MESSAGE_MAP()void Test::ShowTray(bool bShow){ NOTIFYICONDATA...原创 2019-09-26 19:39:56 · 9849 阅读 · 0 评论 -
VC++ TCP编程实例
直接上代码客户端:// TcpClient.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <winsock2.h>#pragma comment(lib, "WS2_32")#include <iostream>#include "../../public/Message.h"using na...原创 2019-09-24 20:09:52 · 10747 阅读 · 0 评论 -
memset陷阱
1、不能用memset操作对象memset甚至会修改虚表指针以下代码会崩溃:class Base{public: virtual void test() { printf("base \n"); }};class Test:public Base{public: virtual void test() { ...原创 2019-09-23 19:57:13 · 10007 阅读 · 0 评论 -
指向静态成员函数和普通成员函数的指针
相当于是熟悉一种语法吧class Test{public: static void StaticFunc() { printf("StaticFunc \n"); } void NormalFunc() { printf("NormalFunc \n"); }};int main(){ voi...原创 2019-09-22 20:17:51 · 10000 阅读 · 0 评论 -
switch语句的缺点及替代方案
前言switch语句是我们经常使用的,在平时的项目中基本不会有什么问题,但是某些场景下,switch的条件分支可能会成千上万个(如服务器或客户端处理消息id的逻辑),这会导致项目难以维护。switch语句缺点大量条件的switch语句缺点如下:每个条件处理逻辑太长,不便查看;当有从1-10000个条件是,如果条件是1w,那么该逻辑要判断上万次;break容易漏写,导致产生不...原创 2019-09-22 19:57:47 · 13388 阅读 · 0 评论 -
C/C++基于TCP的通信协议解决方案
经过本人的分析与项目实战,一种基于收发结构体的方案是非常可靠且方便的。具体方法是,所有的结构体继承自一个结构体,stBase,而stBase的成员只有一个整形的消息id,将收到的消息存到缓冲区后(处理好粘包),将缓冲区强制转换成stBase,通过id来判断对应的业务消息,再强制转换成对应的结构体。消息的定义:这里处理一个基结构体外,只写了两个业务结构体,struct stBa...原创 2019-09-19 21:37:02 · 11560 阅读 · 0 评论 -
符号扩展
符号扩展是指计算机对于小字节转换成大字节的规则。比如char(1字节)转换成int(4字节),多出来的3个字节到底填充什么?规则如下:当扩展一个负数的时候需要将扩展的高位全赋为1.对于正数而言,符号扩展和零扩展是一样的,因为符号位就是0,即全填充0。上面那句话的本意是指:负数扩展后,还是负数,且值不变;正数扩展后还是正数,值不变。看似简单的一句话,可常在面试中让人困惑不已...原创 2019-09-09 20:29:33 · 24284 阅读 · 2 评论 -
开源一个C/C++日志类
前言日志类可以作为一个练手项目,实现一个好的日志类并不容易,这里先出第一个版本,后期持续优化。功能简单对于新手非常友好,欢迎指正错误。介绍该日志类我命名为CClog,第一个C是class的意思,忽略这一点的话可以叫Clog。作用当然是日志记录,写日志操作是线程安全的,支持类似字符串Format的形式。环境基于Windows平台使用案例Demo// test.cpp :...原创 2019-09-05 19:33:53 · 11496 阅读 · 0 评论 -
new二维数组
二维数组本身是不存在的,会被解释成一维数组。比如int a[4][3]在内存中是这番景象:其中int[3]会被认为是一种类型。所以要new二维数组,返回值类型为 int (*pDoubArr)[3] = new [10000][3];解释:返回值为int[3]类型的指针,如同int *pArr = new int[100];返回int类型指针。在一维数组中int是一种类型,int[...原创 2019-09-03 18:56:44 · 10978 阅读 · 0 评论 -
简易string类的实现
在面试的时候,经常会让写一个字符串类,看似很简单的问题,其实经常出错。闲来没事,就写个简单字符串类吧。功能实现容量的概念,size和capacity构造、析构、拷贝构造重载=,+,[]运算符swap交换函数,push_back,pop函数扩容函数右值引用小难点高效的swap交换空字符串类的形式扩容实现必须使用友元函数的operator+右值引用的...原创 2019-08-29 21:31:14 · 9880 阅读 · 0 评论 -
stdcall和cdecl函数调用约定详解
前言看了网上各种关于stdcall和cdecl五花八门的解释,看了后让人初学者完全懵逼,甚至怀疑人生。这里我用通俗易懂的方式,给大家讲解一下原理。首先理解一个知识点,要知道前人为什么要这样做,而不那样做?优点?stdcall和cdecl都是函数调用约定之所以有不同的约定是由于历史原因,而且不同的编程语言有不同的调用约定,若要跨语言调用,则必须要了解函数调用约定。函数调...原创 2019-08-17 21:19:10 · 10524 阅读 · 0 评论 -
回调函数妙用-函数指针
话不多说,上来就是一段代码,之后解释#include "stdafx.h"//定义回调函数类型typedef void(*_CALLBACK)(void *pUser);//设置回调函数void gFunc(_CALLBACK fun,void *pUser){ fun(pUser);}//测试类class Test{public: Test():...原创 2019-08-12 21:58:33 · 10223 阅读 · 0 评论 -
静态成员函数访问非静态成员
有时候我们必须要使用静态成员函数, 比如把静态成员函数的指针传递到别的模块,以实现回调函数的机制,这个时候若不使用普通函数,则必须使用静态成员函数。这时候我们有可能需要本类的非静态成员,具体做法很简单,即将类对象作为静态成员函数的参数即可。class Test{public: Test() :m_id(66) {} static void printMyID(...原创 2019-08-12 21:47:52 · 10784 阅读 · 0 评论 -
子类拷贝构造是否会调用父类的拷贝构造?
有时候我们习惯性的认为在子类拷贝构造的时候会自动的调用父类的拷贝构造,这种观点来自于子类构造时会自动调用父类的构造函数(父类先于子类构造),子类析构的时候会自动调用父类的析构函数(父类后于子类析构)。但实则上子类拷贝构造函数不会自动调用父类的拷贝构造函数——从而导致基类数据缺失的问题代码如下class Base{public: Base() {} Base(con...原创 2019-06-12 22:30:51 · 13504 阅读 · 2 评论 -
二维数组的本质
在C/C++中无论是几维的数组,那必然是连续的内存空间。那对于二维数组,是怎么解释的呢?我们可以这样理解:实则上二维数组也是一个一维的数组,比如int a[5][4] ,这个数组的长度是5,每一个元素又都是一个数组int[4]。从以下代码可以证明二维数组是连续空间,而且正如上面描述的那样:int main(){ int a[5][5]; for (int i...原创 2019-06-02 22:08:30 · 11337 阅读 · 0 评论 -
static关键字总结
1.隐藏。(static函数,static变量均可) 当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。加了static的变量或者函数则只是当前文件可见,所以可以利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。2.static的第二个作用是保持变量内容的持久。(static变量中的记忆功能和全局生存期)存储在静态数据区的变量会......原创 2019-05-31 21:43:32 · 331 阅读 · 0 评论 -
extern的作用
1、声明外部的变量 由于编译是对单个的文件进行编译,所以在编译一个a.cpp文件的时候,若是要在a.cpp中使用b.cpp中的变量,直接使用则编译肯定会报错的,所以这个时候应该永extern修饰在a.cpp中所使用的b.cpp中的变量,这个时候编译器会忽略这个错误,直到链接的时候("将文件融为一体")会找到b.cpp中的变量,这样便ok了。extern的作用相当于让编译器在编译阶段忽...原创 2019-05-30 22:14:21 · 13577 阅读 · 0 评论 -
数组名和数组名取地址的区别
直接上demo,代码如下:int main(){ int arr[10]; printf("%d \n", &arr); //7338716 printf("%d \n", arr); //7338716 printf("%d \n", &arr[0]); //7338716}在上面的代码中,打印出来的结果都是一样的。但是...原创 2019-05-24 22:28:34 · 10114 阅读 · 0 评论 -
游戏开发核心技术之-存档与读档(1)
游戏开发这个领域相对比较神秘一些,会用一些技巧性的编程技术,当然也不难。今天我们就来实现游戏开发领域中的读档与存档功能,并剖析其中的技术点:1、首先我们要知道结构体0数组元素的用途。建议看这篇博客:https://blog.youkuaiyun.com/Think88666/article/details/893025552、new和malloc的本质区别,博客:https://bl...原创 2019-05-24 21:44:36 · 17576 阅读 · 3 评论 -
C/C++获取时间及时间格式转换
window下#include "windows.h"int main(){ SYSTEMTIME s_time; GetLocalTime(&s_time); printf("%04d %02d-%02d %02d:%02d:%02d", s_time.wYear, s_time.wMonth, s_time.wDay, s_t...原创 2019-05-19 11:05:17 · 1347 阅读 · 1 评论 -
使用wofstream写入中文(Unicode)字符时无内容
写入文件时用了中文,所以用wofstream,但写不进去,文件为空用的是STL,后来查了查,这个问题很普遍,微软官方有解决方法,关键是一句://wofstream confFileconfFile.imbue(std::locale("chs"));解决了中文问题https://blog.youkuaiyun.com/nickwar/article/details/56......原创 2019-05-19 09:40:12 · 1222 阅读 · 0 评论 -
vector合并
vector的合并有三种方法:1、当然就是自己写循环来遍历合并了,但是运行效率极低,不推荐这样做2、用merge函数,在头文件<algorithm>中,使用该函数需要注意的: a、合并的目标容器必须要有足够的空间,也就是size的大小必须要够 b、源容器必须要有序代码如下:#include <iostream>#include <...原创 2019-05-11 10:25:45 · 19584 阅读 · 0 评论 -
C++中placement new操作符(经典)
placement new是重载operator new的一个标准、全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的版本)。它的原型如下:void *operator new( size_t, void *p ) throw() { return p; }首先我们区分下几个容易混淆的关键词:new、......原创 2019-04-29 22:59:49 · 1407 阅读 · 0 评论 -
减少使用make_pair
在写代码的时候,我们经常在使用map的时候同样使用着make_pair,例如以下的代码std::map<int,Obj> m;int i = 0;Obj1 obj1;m.insert(make_pair(i,obj1));为什么说make_pair效率很低呢,因为make_pair的返回值是pair对象,会造成什么结果呢?obj1拷贝到临时的pair对象中,临时的p...原创 2019-04-23 21:20:44 · 730 阅读 · 0 评论 -
vector,map以及list性能对比
虽然说map是关联容器,一般关联的数据都使用map来存储,但是实际上vector或者list也是可以代替这样的功能。具体实现可以看https://blog.youkuaiyun.com/Think88666/article/details/89430259比如vector保存一个结构体:struct stData{ int key; int value;}又或者用ve...原创 2019-04-21 11:59:17 · 20200 阅读 · 2 评论