
C/C++
文章平均质量分 75
jiange_zh
linux 网络编程 C++ 算法 数据结构
展开
-
hashmap C++实现分析
一、简介Map 是 Key-Value 对映射的抽象接口,该映射不包括重复的键,即一个键对应一个值。在HashMap中,其会根据hash算法来计算key-value的存储位置并进行快速存取。本文介绍的C++ hashmap,是一个缓存用的hash_map,实现模仿自Java的HashMap,做了一些改造和精简。特点:无读锁, 低写锁, 不删除只添加/更新, 桶不扩容, 按经验值初始...原创 2018-08-12 17:24:50 · 18955 阅读 · 0 评论 -
《深度探索C++对象模型》—构造函数语意学(The Semantics of constructors)
前言这一章中,作者将挖掘编译器对于“对象构造过程”的干涉。构造函数语意学(The Semantics of constructors)Default Constructor 的建构操作你是否有过如下的错觉:没有定义默认构造函数的类,编译器都会生成一个默认构造函数。编译器生成的默认构造函数会明确初始化类中每一个数据成员。C++标准规定:如果类的设计者并未为类定义任何构造原创 2016-09-02 16:55:37 · 1128 阅读 · 1 评论 -
《深度探索C++对象模型》—关于对象(Object Lessons)
前言“本书是由一位编译器设计者针对中高级C++程序员所写的。隐藏在这本书背后的假设是,程序员如果了解C++对象模型,就可以写出比较没有错误倾向而且比较有效率的代码。”正是因为在实际编程中吃了亏,所以才觉得读这本书是十分有必要的,比如之前的一篇博文:http://blog.youkuaiyun.com/jiange_zh/article/details/51871782如果读过这本书,想必也就不会有所困惑了。下面原创 2016-09-02 11:24:12 · 1310 阅读 · 1 评论 -
C++11 std::function、std::bind
1. functionstd::function对象是对C++中现有的可调用实体的一种类型安全的包裹(像函数指针这类可调用实体,是类型不安全的)。关于function的例子:#include < functional>std::function< size_t (const char*) > print_func;// normal function -> std::function object原创 2016-06-06 22:34:07 · 5478 阅读 · 0 评论 -
C++实现根据类名动态生成类对象
在开发后台服务的过程中,我们常常需要从数据库中取数据,并将数据缓存在本地中,另外,我们的服务还需要有更新数据的能力:包括定时的主动更新以及数据库数据更新时服务收到通知的被动更新。之前在需要用到以上功能的时候,模仿着组内通用的数据Cache部分的代码来写,十分方便,基本上只需要自己写两个类:一个是取数据并缓存数据的类XXXData,一个是扇出数据的类XXXFetcher。在需要使用数据的时候,通过:F原创 2016-08-09 22:33:22 · 12267 阅读 · 2 评论 -
C++侵入式智能指针的实现
简介在现代C++编程中,智能指针给我们在资源管理上带来了很多好处,这里就不多说了。在工作中,我们常常会用智能指针来管理资源,其中最常用的就是引用计数类智能指针了(shared_ptr)。资源共享型的智能指针有两种实现,一种是侵入式,一种是非侵入式。在教材里比较常见的是非侵入式的,它的实现完全放在智能指针模板里,模板类有一个用于保存资源类对象的指针变量,和一个用于记录资源对象使用计数的指针变量,这两个原创 2016-09-12 13:07:23 · 4762 阅读 · 0 评论 -
C++模板阶段性小结
以前在学校C++模板用的比较少,碰到的问题也就少。 而在工作中模板的使用随处可见,在遇到问题中学习,也就对模板有了新的认识和理解。下面是一个简单的小结。模板本身不是类或函数首先这一点是需要最先明确的,之前就是没有理解这一点,所以对模板的认识一直停留在表明。我们借助以下例子来理解这一个点:template class AutoList{ public:原创 2016-08-20 15:02:03 · 1997 阅读 · 0 评论 -
实习点滴 - 破窗理论、C++ 函数模板静态库
最近在搬砖,本以为仅仅是体力活而已,无奈自己功力不够,处处碰壁。这次的需求及其背景:业务中有一个recommendId的东西,类型是string或者vector< char >。第一个字节(即recommendId[0])用来标识数据所属的类型,比如4代表商业化广告,5代表游戏广告等,然后后面的字节或者是string类型的数据,或者是jce类型的数据(这个即为编码协议)。最近开始推广使用新的协议,第原创 2016-07-28 00:10:53 · 2348 阅读 · 0 评论 -
C++调用空指针对象的成员函数——静态绑定与动态绑定
最近代码中看到调用空指针对象的成员函数的写法,联想起上次碰到的问题:C++类的成员函数存储方式(是否属于类的对象)两者的本质是一样的,上次只是简单地讨论了下,这次从编译器的角度,来谈一谈这个知识点。一个简单的例子:class MyClass { public: int i; void hello() { printf("hello\n"原创 2016-08-06 13:31:09 · 2159 阅读 · 0 评论 -
实习点滴 - 跟一个蠢bug学习多线程调试、线程安全和可重入函数
昨天同事帮忙review代码的时候,发现我代码里使用了一个非线程安全的函数localtime,并建议我使用线程安全的localtime_r。于是我查了一下相关资料:time 与 gettimeofday 两个函数得到的都是从Epoch开始(1970-1-1, 00:00:00)到当前的秒数(tt=tv.tv_sec),而后者还能得到更精细的微秒级结果,即tv_sec*(10^6)+tv_usec为从原创 2016-07-30 10:41:54 · 4610 阅读 · 0 评论 -
Windows下使用Eclipse搭建C++开发环境
之前在学校的时候,没怎么写过大型的代码,所以对编辑器都很随便。 一开始C++入门的时候就用了非常简单的Dev C++(写算法题之类的已经十分足够了)。 后来接触linux,开始使用vim,不过也只是很简单的用一用,代码量常常也不超过3000行。 而偶尔写网站用eclipse或者MyEclipse。 总的来说,对我而言,还没有一个比较常用、熟悉的编辑器。来到公司之后,同事推荐我使用eclips原创 2016-07-03 13:18:02 · 20410 阅读 · 0 评论 -
C++类的成员函数存储方式(是否属于类的对象)
今天在看TAF源码的时候,发现下面一段有趣的代码:getSmallerProxyPrx = Application::getCommunicator()->stringToProxy<GetSmallerPrx>(MobileAssist.JiangeSmallerServer.GetSmaller);//此处T为GetSmallerPrxtemplate<class T> T stringTo原创 2016-07-10 15:42:41 · 4646 阅读 · 2 评论 -
【C++编译】gcc的-l参数和-L参数
今天在编译服务的时候,出现了一个错误:/usr/bin/ld: cannot find -lxxx于是查了一下,这个错误是因为链接程序ld在指定目录里找不到libxxx.so这个库。那么,上面所说的“指定目录”是哪些目录,以及 -l的作用是什么呢?-l参数:用来指定程序要链接的库,-l参数紧接着就是库名。这里的库名并非真正的库文件名。以库名为math的库为例,他的库文件名是libmath.so或者原创 2016-06-23 23:15:24 · 9438 阅读 · 0 评论 -
C++编译链接原理简介
在实习的过程中,偶尔会在编译代码的时候出现莫名其妙的链接错误,或者更惨的是,编译链接通过了,运行的时候出现莫名其妙的coredump,查了半天原来是.a静态库更新了导致.h文件和.o文件不一致。受够了被这些错误支配的恐惧,所以决定补充一下这方面的知识。以下内容参考自网络。几个概念:1、编译:编译器对源文件进行编译,就是把源文件中的文本形式存在的源代码翻译成机器语言形式的目标文件的过程,在这个过程中,原创 2016-08-11 23:43:05 · 5091 阅读 · 4 评论 -
《深度探索C++对象模型》—Function语意学(The Semantics of Function)
Function语意学(The Semantics of Function)Member的各种调用方式Nonstatic Member FunctionsC++的设计准则之一:nonstatic member function 至少必须和一般的nonmember function有相同的效率。编译器内部会将“member函数实体”转换为对等的“nonmember函数实体”://1. 改写函数签名,安原创 2016-09-03 11:51:20 · 1097 阅读 · 0 评论 -
C++突破private访问权限的黑科技
昨天,有位同事抛出了一个问题:一个class内有一个private属性的struct类型,然后他想做的事情是,在继承该class的子类中复用这个类型,但是由于该类似的private属性,编译是不通过的。因此就引入了一个问题:如何突破class的private属性限制——试图破坏class的封装性,有点“逆天而行”的感觉。查了一下,方法确实是有的。假设有以下类:m_nPrivateclass X{原创 2016-08-12 14:10:06 · 3847 阅读 · 0 评论 -
语法糖:萃取lambda表达式
背景现在手头主负责的服务代码,基本上都用C++11来开发了,异步编程使用的是TAF的future/promise。future的then函数,接受的是一个Callback对象,该对象通过promise::bind来生成。Callback和bind是参考chromium的base::Callback,base::Bind实现的,该版本并不支持C++11,所以bind() 不接受 lamb...原创 2018-06-22 11:39:39 · 3806 阅读 · 0 评论 -
C++11常用新特性快速一览
最近工作中,遇到一些问题,使用C++11实现起来会更加方便,而线上的生产环境还不支持C++11,于是决定新年开工后,在组内把C++11推广开来,整理以下文档,方便自己查阅,也方便同事快速上手。(对于异步编程十分实用的Future/Promise以及智能指针等,将不做整理介绍,组内使用的框架已经支持并广泛使用了,用的是自己公司参考boost实现的版本)1. nullptrnullptr ...原创 2018-02-23 19:28:13 · 126689 阅读 · 38 评论 -
【后台开发拾遗】异步代码同步化
在当今的编程世界中,异步编程已经成为了一种习惯。传统的同步阻塞编程,虽然处理流程非常清晰,但是程序常常处于阻塞等待状态,CPU资源利用率低。而早期的异步编程,通过callback的方式进行回调处理,当回调嵌套开始多起来的时候,程序代码可读性变得非常差。 对于C++,协程和Future/Promise的出现,使得我们既可以实现异步编程,又可以将代码写得十分优美,看起来跟同步代码一般清晰。本文再次回顾原创 2017-10-05 19:35:17 · 1855 阅读 · 0 评论 -
C++中两个类中互相引用
有时候,我们会有两个类需要互相引用的场景,由于两个类的定义是有顺序的,因此两个类相互引用,不管哪个类在前面,都会出现有一个类未定义的情况。这时可以通过类的前置声明来提前告诉编译器,所要引用的是个类,但由于此时后面的那个类还没有定义,因此无法给对象分配确定的内存空间,故只能使用类指针而不能是类实体。// A.h#include "B.h"class A{public: A(B* pB)原创 2017-10-02 15:18:51 · 2719 阅读 · 0 评论 -
makefile 入门知识备忘
前言在windows下,编译、链接工作就是一个按钮的事情,IDE帮你把大部分工作都做了。这当然非常方便,但是如果你对背后的工作原理不了解,就经常会出现一些自己无法解决的、莫名其妙的编译、链接错误。在linux下,离开了IDE,要编译一个大型工程,就需要借助makefile了。makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更原创 2017-05-14 11:29:34 · 1403 阅读 · 0 评论 -
【C++后台开发面试】C++语言相关
推荐书籍:《C++primer》相关读书笔记专栏:重学C++之读书笔记1. 虚函数实现多态所必须, 当有虚函数时,类会有一个虚表,对于一个实例,会有一个虚指针(只有一个)指向虚表,执行前查表。有子类时,析构函数必须是虚函数。构造函数不能是虚函数(指针未构造)。构造析构调用虚函数不起作用:未初始化 or 已被销毁。另一个优点:实现封装。2. 智能指针智原创 2017-05-12 12:17:13 · 2899 阅读 · 1 评论 -
《Linux多线程服务端编程》—muduo网络库(1)
TCP网络编程本质论思维转换:把原来“主动调用recv(2)来接收数据,主动调用accept(2)来接受新连接,主动调用send(2)来发送数据”的思路转换为“注册一个收数据的回调,网络库收到数据会调用我,直接把数据提供给我,供我消费。注册一个接受连接的回调,网络库接受了新连接会回调我,直接把新连接对象传给我,供我使用。需要发送数据的时候,只管往连接中写,网络库会负责无阻塞地发送。”作者(陈硕)认为原创 2016-09-07 23:39:22 · 2877 阅读 · 0 评论 -
【利器】Vim配置成IDE方案以及使用
“工欲善其事必先利其器”。在之前就一直打算把vim作为自己的编辑器来工作的,但是由于vim的配置比较复杂,自己也还不知道自己需要哪些功能,并且公司的办公机器是windows系统,linux开发机器则不方便装自己的软件,所以暂时用的是windows下的eclipse。eclipse用了3个月,也大概知道自己在工作中需要哪些功能了。总的来说,eclipse的功能很全面,基本够我用了,但是个人比较喜欢vi原创 2016-09-18 20:41:27 · 2955 阅读 · 1 评论 -
《Linux多线程服务端编程》—线程同步精要
并发编程的两种基本模型:message passing 和 shared memory。使用message passing 可以跨机器,分布式系统的架构更具有一致性,扩容起来也较容易。线程同步的四项原则按重要性排序:首要原则是尽量最低限度地共享对象,减少需要同步的场合。一个对象能不暴露给别的线程就不要暴露;如果要暴露,优先考虑immutable对象;实在不行才暴露可修改的对象,并用同步措施来充分保原创 2016-09-06 14:16:50 · 2567 阅读 · 1 评论 -
《Linux多线程服务端编程》—线程安全的对象生命期管理
当一个对象能被多个线程同时看到时,对象的销毁时机变得模糊不清,可能出现多种竞态条件(race condition): 1. 在即将析构一个对象时,从何而知此刻是否有别的线程正在执行该对象的成员函数? 2. 如何保证在执行成员函数期间,对象不会在另一个线程被析构? 3. 在调用某个对象的成员函数之前,如何得知这个对象还活着?它的析构函数会不会碰巧执行到一半?线程安全的定义依据[JCP],一个线程原创 2016-09-05 00:08:13 · 1090 阅读 · 0 评论 -
C/C++静态库链接原理
前面我们学习了编译链接的一些知识,现在来看看静态库链接的一些知识~静态库本质上就是使用ar命令打包一堆.o文件:$ ar -r test.a myObj1.o myObj2.o静态库没有标准,不同的linux下都会有些细微的差别。大致的格式:Global header----------------- +-------------------------------File hea转载 2016-08-12 21:57:20 · 3389 阅读 · 0 评论 -
C++异步调用利器future/promise实现原理
前言在异步编程中,各种回调将让人眼花缭乱,代码分散,维护起来十分困难。boost和C++11 的 future/promise 提供了一个很好的解决方案,使得代码更加漂亮、易维护。在工作中,我也用过几次future/promise,但是还是十分生疏,所以决定学习下它的原理,用起来才更加顺畅。查了很多资料,发现很多语言都有这个机制,但是关于C++的promise的资料却很少,只有一些使用的教程,而没有原创 2016-09-14 23:24:42 · 28923 阅读 · 10 评论 -
C++11 多线程 future/promise简介
1. < future >头文件简介Classes std::future std::future_error std::packaged_task std::promise std::shared_futureFunctions std::async std::future_category2. std::future简单来说,std::future提供了一种访问异步操作结果的原创 2016-06-07 13:29:27 · 34494 阅读 · 3 评论 -
【Linux环境编程】内存管理:函数栈空间,虚拟内存及其分配
一.函数调用栈空间的分配与释放函数执行时有自己的临时栈空间,c++成员函数有两个临时栈空间,一个是成员函数的还有一个是对象的。函数的参数是压进临时栈中,传递的实参用来初始化临时栈中的形参。函数属性:int __attribute__((stdcall)) add(int a, int b){ return a+b;}一共有3种属性(调用方式):stdcall,c原创 2015-11-22 21:19:32 · 1487 阅读 · 0 评论 -
【slighttpd】基于lighttpd架构的Server项目实战(11)—C++的Name Mangling
上一节中,我们介绍了插件作为动态库的加载,其中我们注意到 函数:void* dlsym(void* handle,const char* symbol)返回的是【symbol对应的地址】。因此,在我们开发的插件中,SetupPlugin和RemovePlugin函数需要添加extern “C” :extern "C" Plugin* SetupPlugin(){ return new M原创 2016-02-12 14:03:53 · 2333 阅读 · 0 评论 -
重学C++ (五) 函数
第七章 函数1.函数不能返回另一个函数或内置数组类型,但可以返回指向函数的指针,或指向数组元素的指针;2.函数必须指定返回类型;返回类型不是void的函数必须返回一个值,但有一个例外:main函数可以没有返回值就结束(编译器会隐式插入返回0的语句);3.指针形参:void reset (int *ip){ *ip = 0; //改变ip所指对象的值 ip =原创 2016-01-13 15:25:49 · 611 阅读 · 0 评论 -
重学C++ (四) 语句
第六章 语句1.一些看似非法的分号往往只不过是一个空语句而已:ival = v1 = v2;; //ok上面一共两条语句:一条表达式语句和一条空语句;2.对于switch结构,漏写break语句是常见的错误;3.switch求解的表达式可以非常复杂,而case标号必须是整型常量表达式;//非法标号值case 3.14; //非整型case ival; //非常量4.只能在最后一个case标号或d原创 2016-01-12 09:42:26 · 750 阅读 · 0 评论 -
浅谈回调函数——以sort中的cmp为例
最近在看一些源码,碰到一个概念:回调函数。虽然之前就接触过,但还是对它存在一些疑惑。所以查找了一些资料,结合学到的知识,在这里我做一个简单的介绍,希望能够帮助初学者明白“callback函数”究竟是什么。一个常见的例子也许你还不知道,自己已经用过回调函数了。下面这段代码想必大家都很熟悉:#include<iostream>#include<algorithm> using namespace原创 2016-01-11 15:30:48 · 2134 阅读 · 0 评论 -
重学C++ (二) 数组和指针
第四章 数组和指针1.数组的维数必须用值大于等于1的常量表达式定义,非const常量以及要到运行阶段才知道其值的const变量都不能用于定义数组的维数;2.注意下面两种初始化的区别:char c1[] = {'C', '+', '+'}; //末尾没有null,3维char c2[] = "C++"; //末尾有null,4维;char c3[3] = "C++"; //error3.数组下标的原创 2016-01-11 10:27:18 · 874 阅读 · 0 评论 -
重学C++ (一) 变量和基本类型、标准库类型
前言大一的时候我就已经学过C++程序设计了,但是我从来不敢跟别人说我会C++。事实上,平时里大多数时候我用的是C++里面C的部分,偶尔用一下类来封装(其实用struct也可以实现的)。对于C++的特点,我一直没有很好的去学习,只是略知一二,所以在实际使用中常常会出现一些难以察觉的问题。我举个很简单的例子,我们打算输出一个vector内的元素:#include <iostream>#include原创 2016-01-10 18:17:30 · 1508 阅读 · 0 评论 -
【C++】一道考察重载、覆盖、多态的题目
代码:#include <iostream>#include <string>using namespace std;class A{protected: int m_data;public: A(int data = 0) { m_data = data; } int GetData() { return原创 2015-12-07 20:11:41 · 1641 阅读 · 0 评论 -
重学C++ (十) OOP面向对象编程(1)
面向对象编程基于三个基本概念:数据抽象、继承和动态绑定。在C++中,用类进行数据抽象,用类派生从一个类继承另一个类:派生类继承基类的成员。动态绑定使编译器能够在运行时决定是使用基类中定义的函数还是派生类中定义的函数。1.多态性仅用于通过继承而相关联的类型的【引用或指针】;2.通过基类的【引用或指针】调用【虚函数】时,发生动态绑定。引用或指针既可以指向基类对象也可以指向派生类对象,调用的虚函数在运行时原创 2016-01-26 11:03:53 · 1225 阅读 · 0 评论 -
重学C++ (九) 重载操作符与转换
1.重载操作符必须具有至少一个类类型或枚举类型的操作数(内置类型的操作符含义不能改变);2.除了函数调用操作符operator()之外,重载操作符时不能使用默认实参;3.重载之后&&, ||不再具备短路求值特征;4.作为成员函数的操作符有一个隐含的this形参,限定为第一个操作数; 一般将算数和关系操作符定义为非成员函数,而将赋值操作符定义为成员://成员函数Sales_item& Sales_原创 2016-01-25 14:50:36 · 1120 阅读 · 0 评论 -
C++11 浅谈 右值引用和move语义
一、左值和右值lvalue: 具有存储性质的对象,要实际占用内存空间、内存地址;位于赋值运算符左边时可以赋值(同时也可以用在右边)。rvalue:没有存储性质的对象, 也就是临时对象。位于赋值运算符左边时不可赋值。例子:int a = 10;int b = 20;int *pFlag = &a;vector<int> vctTemp;vctTemp.push_back(1);string原创 2016-01-24 18:49:22 · 2526 阅读 · 1 评论