c/c++
文章平均质量分 76
jlaij
这个作者很懒,什么都没留下…
展开
-
c++ 实现函数进入退出记录
#pragma once#include <functional>template<class T>class GuardCls{public: using param_t = typename std::conditional<std::is_reference<T>::value || std::is_pointer<T>::value, T, T&>::type; using func_t = std::functi.原创 2020-12-02 14:55:34 · 493 阅读 · 0 评论 -
c++实现流式写日志
#include <iostream>#include <sstream>class logstream{public: template<typename T> inline logstream& operator<<(const T& log) { m_oss << log; return *this; } inline logstream& operator<<(std::ost.原创 2020-12-02 14:18:02 · 804 阅读 · 1 评论 -
c++ 实现对象池
c++ 简单实现一个管理对象池ObjPool.h#pragma once#include <iostream>#include <queue>#include <memory>using namespace std;static constexpr int32_t pool_step = 3;template<typename T>class ObjPool{ using shared_obj_t = shared_ptr<原创 2020-05-26 15:05:39 · 399 阅读 · 0 评论 -
基于事件驱动网络服务器实现
socket 的事件类型有 读事件(socket链接也属于读事件)、写事件、socket 关闭事件事件处理方式无非就是添加事件、删除事件、分发执行事件大致逻辑就是:事件驱动的网络实现逻辑while(true): EventOp->dispatch() // 由 select或epoll 进行事件监听 将监听的事件添加到事件列表里 for(ev : event_list): if ev & ev_read && fd 是...原创 2020-05-17 22:15:03 · 515 阅读 · 0 评论 -
c++ 获取socket接收缓存大小
#ifdef SF_PLATFORM_WIN u_long readn = DEFAULT_SOCKET_READ_LEN; if (sf_ioctlsocket(fd, FIONREAD, &readn) < 0) return -1; return (int)readn;#else int n = DEFAULT_SOCKET_READ_LEN; if (sf_ioctlsocket(fd, FIONREAD, &n) < 0) return -1; .原创 2020-05-17 21:49:30 · 1140 阅读 · 0 评论 -
c++完整实现地图寻路A星算法
A星寻路算法的讲解有很多,这里不再论述,只给出实现程序。AStar.h#pragma once#include <vector>#include <map>#include <queue>// 二维地图A*算法实现const int OBLIQUE = 14; // 斜线移动权重为14const int STEP = 10;struct Point{ Point(int id, int reachable); ~Point(); v原创 2020-05-15 22:52:07 · 2924 阅读 · 0 评论 -
linux 设置core 生成及命名 路径
linux下设置coredump文件的开关和路径ulimit -c unlimited 不限制生成core文件大小ulimit -c 0 关闭core文件生成开关ulimit -c 1024 限定生成core文件的大小为10242.core文件的命名规则/proc/sys/kernel/core_uses_pid 1 表示使用procid命名,0表示不使用/proc/sys/kern...原创 2020-01-22 11:04:54 · 1012 阅读 · 0 评论 -
日志输出 __FIFL__输出路径太长处理
程序log日志打印时 __FIFL__输出路径太长处理windows项目属性-》c/c++ -》所有选项使用完全路径 否 调试信息格式 程序数据库(Zi)Linux如果是使用CMAKE编译的,在CMakeLists.txt中添加这么一行(C++语言需要将CMAKE_C_FLAGS换成CMAKE_CXX_FLAGS)set(CMAKE_C_FLAGS "${CMAKE_C_...原创 2020-01-21 13:26:53 · 696 阅读 · 0 评论 -
c++ 实现高效缓存(链式buffer)
如果我们从网络端接收的数据是不定长度的,不能提前分配好网络缓存大小,则可以选择使用链式缓存的实现方式。链式缓存主要是分配固定大小的缓存链保存数据,一个管理器去管理这些缓存链。链式缓存示例://一种链式缓冲//ringbuffer是固定长度,不能够扩展,链式buffer可以任意扩充/** * buffer * *first--chain buffer [1024] * ...原创 2019-12-06 00:23:02 · 3489 阅读 · 1 评论 -
c++ 实现循环缓存buffer
循环buffer是一种高效缓存方式,一般用于接收固定长度协议使用。如果使用不断扩展的缓存操作(见:https://blog.csdn.net/chinabhlt/article/details/102751880),则我们必须要malloc不断扩张缓存,还会memcpy或memmve操作,效率比较低,而ringbuffer则很好的规避这些低效操作。如果协议长度是固定的,则可以使用ringbuffe...原创 2019-12-05 23:56:24 · 2041 阅读 · 1 评论 -
基于事件方式实现的高效网络库
一个网络处理通常是我们通过epoll接收读事件,然后从网络层读取数据放入缓存中,在从缓存中读出数据,进行协议解析分发处理消息。一个消息过来通常是需要进行应答的,所以我们还需要将回复信息进行封包发送到网络层。1、网络接收相对比较慢,消息传递情况比较复杂,我们通常是需要进行缓存,然后分发,linux下通常是使用epoll进行消息接收。2、缓存需要很好的设计,尽量防止多次拷贝处理。3、通常网...原创 2019-11-30 09:13:50 · 260 阅读 · 0 评论 -
shared_ptr使用注意
使用shared_ptr需要注意的问题1、不要用一个原始指针初始化多个shared_ptrint*d=newint;std::shared_ptr<int>p1(d);std::shared_ptr<int> p2(d);2、不要在函数实参中创建shared_ptr。因为C++的函数参数的计算顺序在不同的编译器下是不同的。正确的做法是先创建好...原创 2019-09-26 10:31:03 · 452 阅读 · 0 评论 -
vs编译中遇到的错误问题
1、error:LNK2019:无法解析的外部符号_imp_closesocket需要加入库文件ws2_32.lib2、应用程序没有调用 WSAStartup添加以下代码即可:#include <WinSock2.h> WSADATA wsaData; int nRet; if ((nRet = WSAStartup(MAKEWORD(2, 2...原创 2019-11-25 18:14:38 · 632 阅读 · 0 评论 -
MariaDB数据库使用及配置
1、windows 环境下配置及使用1、下载 MariaDB (https://mariadb.com/)进行安装注意,windows下安装会报一个service 权限错误,先不要退出,进入本地服务(进入设置面板搜索服务),找到mariadb,打开mariadb服务属性面板,选择登录tab,选择本地系统账户,然后点击重试,安装完成。2、下载 MariaDB (connector-c/c...原创 2019-11-22 15:24:24 · 1404 阅读 · 0 评论 -
对象池简单实现
一个简单内存池实现Lock.hpp#pragma once#include <mutex>#include <condition_variable>typedef std::mutex Mutex;typedef std::recursive_mutex RecursiveMutex;typedef std::lock_guard<Recursi...原创 2019-11-04 19:24:31 · 203 阅读 · 0 评论 -
基于epoll实现高性能服务器模型
原创 2019-10-31 23:22:46 · 227 阅读 · 0 评论 -
cpp实现线程池-半同步半异步
Lock.h#pragma once#include <mutex>#include <condition_variable>typedef std::recursive_mutex RecursiveMutex;typedef std::lock_guard<RecursiveMutex> RecursiveLock;typedef st...原创 2019-10-30 00:19:49 · 506 阅读 · 0 评论 -
消息处理机制
游戏服务器消息处理机制一般mmo大型游戏都会有多个服务器进程构成,比如 gate、login、scene、world、db、node(进程节点管理也叫服务器管理服)只有gate与玩家进行交互,gate接到玩家消息会转发到不同服,不同服进行对消息处理,并返回给gate,gate在将消息发给玩家。消息通常是使用的都是protobuf。玩家请求消息,以排行为例:message rankA...原创 2019-10-29 19:54:27 · 344 阅读 · 0 评论 -
跳跃表代码完整实现
跳跃表实现#include <iostream>#include <stdlib.h>#include <time.h>#include <memory>using namespace std;const int MaxLevel = 10;int RandomLevel(){ int k = 1; while...原创 2019-10-28 23:25:32 · 937 阅读 · 0 评论 -
vector 删除元素的几种方式
//vector 删除元素方式#include <vector>#include <iostream>#include <algorithm>using namespace std;int main(int argc, char const *argv[]){ vector<int> vec; for (int i =...原创 2019-10-27 20:46:42 · 9453 阅读 · 1 评论 -
c++11 lambda总结
C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。Lambda的语法形式如下: [函数对象参数] (操作符重载函数参数) mutable或exception声明 ->返回值类型 {函数体} 可以看到,Lambda主要分为五个部分:[函数对象参数]、(操作符重载函数参数)、mutable或exception声明、->返...转载 2019-10-27 20:27:28 · 141 阅读 · 0 评论 -
高效定时器实现方式
一般比较定时器的实现方式有几种1、升序时间链表,然后tick轮询方式2、使用时间轮的方式,主要是解决定时器过多,插入时间链表的时间会增长的情况.设定n个槽位,每个槽是一个时间链表假设有60个槽,每个槽的tick是1s,超时的设定跟槽关系就是 槽位置ts = (cur+(timeout/tick)) % 60, rotation = (timeout/tick )/603、使用最小堆...原创 2019-10-27 20:00:20 · 333 阅读 · 0 评论 -
cpp 可变参数模板传递任意类型参数实现
#include <iostream>#include <variant>#include <vector>#include <string>using namespace std;class Data{public: Data() {} virtual ~Data() {}};template <typ...原创 2019-10-27 16:43:33 · 915 阅读 · 0 评论 -
利用Snowflake 算法生成唯一id
总共64位数字//最高1位不使用,41位毫秒时间,12位中间数(6位机器码,6位进程号),10位毫秒序列SnowFlake.h#pragma once#include <cstdint>#include <chrono>#include <unistd.h>using namespace std;class SnowFlake{...原创 2019-10-27 00:02:58 · 761 阅读 · 0 评论 -
c++ 常用buffer实现
1、一个buffer缓存简单实现#include <cstdio>#include <cstring>#include <stdlib.h>#include <malloc.h>class Buffer{public: Buffer() { m_buf = (char *)malloc(m_incr...原创 2019-10-26 00:09:54 · 4649 阅读 · 0 评论 -
提高C++性能的编程技术笔记:总结
《提高C++性能的编程技术》这本书是2011年出版的,书中有些内容的介绍可能已经过时,已不再适用于现在的C++编程中,但大部分内容还是很有参考意义的。这里是基于之前所有笔记的简单总结,笔记列表如下:跟踪实例:https://blog.csdn.net/fengbingchun/article/details/83449625构造函数和析构函数:https://blog.csdn.net...转载 2019-10-12 12:19:38 · 119 阅读 · 0 评论 -
判断回文字符串
简单判断字符串是否为回文字符串 #include#includeint find(char *str,int n){ if(n<=1) return 1; else if(str[0] == str[n-1]) return find(str+1,n-2); else return 0;}int main(int argc, char* argv[]) {原创 2013-04-02 20:16:48 · 697 阅读 · 0 评论 -
快排序
简单实现快排序#includevoid quicksort(int a[],int s,int e){ //从a[s]到a[e]进行排序 int tmp; int i=s,j=e; if(s<e){ tmp = a[s]; while(i!=j){ while(itmp) --j; if(i<j){ a[i] = a[j]; ++i;原创 2013-04-02 20:30:11 · 574 阅读 · 0 评论 -
折半查找
折半查找的简单实现:折半查找需要先对数据进行排序,然后进行查找#include#include#include#define GET_ARRAY_LEN(array,len) {len = (sizeof(array)/sizeof(array[0]))}int bin_search(int a[],int n,int key){ int low,high,mid; low = 0;原创 2013-04-02 20:07:12 · 535 阅读 · 0 评论 -
查找字符串中第一个不重复的字符
查找字符串中第一个不重复的字符一般有三种方法实现:1、先对字符串排序然后一次对比查找2、使用flag数组作标记3、使用hash数组以下代码是第三种方法实现:#include#include#define MAX_SIZE 50int main(){ int i,loc; char *str = "aabccbdeffe"; int len = strlen(str原创 2013-04-03 19:19:40 · 1873 阅读 · 0 评论 -
用C语言实现面向对象的开发
C语言的对象化模型 面向对象的特征主要包括:.封装,隐藏内部实现.继承,复用现有代码.多态,改写对象行为采用C语言实现的关键是如何运用C语言本身的特性来实现上述面向对象的特征。1.1 封装封装是一种信息隐蔽技术,它体现于类的说明,是对象的重要特性。封装使数据和加工该数据的方法(函数)封装为一个整体,以实转载 2013-04-04 20:51:01 · 547 阅读 · 0 评论 -
插入排序
简单实现的插入排序#include#define LEN 5int a[LEN] = { 10, 5, 3, 9, 7};void insertion_sort(){ int i, j, key; for(j = 1;j < LEN; j++){ key = a[j]; i = j - 1; while原创 2013-04-02 20:27:16 · 492 阅读 · 0 评论 -
奇怪的面试题
某网站看到的奇怪面试题:#includeint main(){ if( ?){ printf("Hello"); }else{ printf("World!\n"); }}要求if添写什么条件打印出:Hello World!,是不是很怪异?答案如下:#includeint main(){ if(!print转载 2013-04-03 18:41:13 · 637 阅读 · 0 评论 -
c语言实现字符串分割
c语言简单分割字符串:#include#includeint main(){ char oldstr[]="hahaha:hehehe-xixixi heiheihei"; char *newstr=""; char *splitstr=":- "; newstr = strtok(oldstr,splitstr); while(newstr !=NULL){原创 2013-04-07 16:19:34 · 1236 阅读 · 0 评论 -
c语言实现随机数
c语言简单实现产生随机数:第一种方法是:#include#include#includeint main(){ int i,j; srand((int)time(0)); for(i=0;i<10;i++){ j = (int)(10.0*rand()/RAND_MAX+1.0); printf("%d ",j); } return 0;原创 2013-04-07 17:39:31 · 1055 阅读 · 0 评论 -
c语言实现二叉树及前中后序遍历
c语言实现二叉树及前中后序遍历(采用递归遍历方式)#include#include#include//定义二叉树节点typedef struct BTNode{ char data; struct BTNode *rchild,*lchild;}BTNode,*BTtree;BTtree createBTNode(BTtree ptr, char value, cha原创 2013-04-09 20:21:28 · 3292 阅读 · 0 评论 -
求解二叉树的深度
简单求解二叉树的深度算法(二叉树以链表形式存储)int getdepth(BTNode *p){int LD,RD;if(p == NULL){return 0;}else{LD = getdepth(p->lchild);RD = getdepth(p->rchild);return (LD>RD?LD:RD)+1;}}原创 2013-04-09 20:34:50 · 822 阅读 · 0 评论 -
二叉树层次遍历
二叉树利用队列按层次遍历算法如下:void levelorder(BTNode *p){ int front,rear; BTNode *que[maxsize]; front = rear = 0; //构造循环队列 BTNode *q; if(p != NULL){ rear = (rear+1)%maxsize; que[rear] = p; whil原创 2013-04-09 20:46:34 · 1005 阅读 · 1 评论 -
我们很容易忽略的c语言知识(二)
这是我几天前发过的一段错误代码:#include#include#includeint main(){char *alice; //没有分配内存空间printf("请输入alice说的话\n");scanf("%s",alice);printf("%s\n",alice);}为什么无法打印输入的字符串?我想曾经很多人都犯过这样的错误,却无法找原创 2013-04-10 11:28:15 · 624 阅读 · 0 评论 -
swap函数的三种写法
第一种写法:void swap(int *a, int *b){int temp;temp = *a;*a = *b;*b = temp; }第二种写法:void swap(int *a, int *b){*a = *a + *b;*b = *a - *b;*a = *a - *b;}第三种方法:void swap(i原创 2013-04-11 17:26:56 · 1674 阅读 · 0 评论