Apr 12, 2022 · 925 words · 2 mins
背景 # 每一个cpp expression都有一个type 和 value category 属性 前者大家都比较了解,但是后者却常常被忽视
Value Categories in the c language # cpp是由c语言发展而来,因此这里先介绍c 语言中的value category
Mar 5, 2022 · 2261 words · 5 mins
梳理 shared_ptr 的控制块、引用计数、线程安全边界和常见使用陷阱。
Mar 5, 2022 · 1400 words · 3 mins
背景 # 一种很常见的背景是,需要表示未知类型的数据。比如可能是用户提供的数据,也可能是一个 Cache 的实现,其 value 想支持任意类型的数据
对于这种场景,c 语言出身的开发者通常会使用 void* 来实现
Sep 30, 2018 · 1397 words · 3 mins
把 std::async、std::packaged_task、std::promise 三个放在一起来说,是因为它们都可以返回一个 std::future 对象。简单来说,当某个线程需要等待一个特定的一次性事件(one-off event),它可以用一个 “future” 来表示这个事件。
Sep 23, 2018 · 776 words · 2 mins
condition_variable 类是同步原语,能用于阻塞一个线程,或同时阻塞多个线程,直至另一线程修改共享变量(条件)并通知 condition_variable 。
用人话来说,condition_variable,也就是条件变量,是线程间通信的一种方式。
Sep 20, 2018 · 486 words · 1 min
多线程保护数据时,一种较为特殊的情况是只需要保护资源的初始化。
资源初始化一般遵循"lazy initialization"的原则,也就是在用到该资源最近的地方再初始化。
Sep 9, 2018 · 1461 words · 3 mins
背景 # move semantics 是 modern cpp 中非常重要的特性,有必要详细了解一下。
update time:2022 年 7 月 2 日
move semantic # 基本的内容大家都很熟悉,就不说了
Sep 9, 2018 · 955 words · 2 mins
起因是在看《CplusplusConcurrencyInAction_PracticalMultithreading》的时候,里面讲到初始化 std::thread 的时候,如果 thread function 的参数列表中有引用,需要传入 std::ref 才可以得到符合预期的结果。
Sep 1, 2018 · 565 words · 2 mins
最近在学习node.js,里面讲到node.js的事件机制使用了观察者模式,因此来学习一下。
观察者模式的目的是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
Aug 28, 2018 · 546 words · 2 mins
目的是忽略单一对象和组合对象的不同。 有点像以前写过的用链表定义一个树结构,每个节点是一个val + 多个tree 。如果某个节点是叶子节点了,那么对应的tree都为NULL. 只不过这里用了更加面向对象的实现。
Aug 23, 2018 · 322 words · 1 min
用人话就是,主线程传给附属线程一个promise Object,然后主线程想要获取附属线程set给promise Object的值(也就是该线程返回的某个结果),需要通过主线程中的promise object 得到对应的future object(每个promise 对应一个 future),然后调用future 的get方法。如果附属线程没有执行作为参数传入的promise的set方法去返回结果,那么程序就会block住。
Aug 21, 2018 · 197 words · 1 min
1 std::vector<unsigned char> readFromFile1(const char* filePath) { 2 FILE* file = fopen(filePath, "rb"); 3 std::vector<unsigned char> result; 4 if (file == nullptr) { 5 return result; 6 } 7 8 // 获取文件大小,尽量一次读完 9 size_t fileSize = getFileSize(file); 10 if (fileSize != 0) { 11 result.resize(fileSize); 12 size_t n = fread(&result[0], 1, fileSize, file); 13 assert(n <= fileSize); 14 if (n != fileSize) { 15 result.resize(n); 16 } 17 } 18 19 // 在读取过程当中,有可能文件大小有变化,再尝试读取 20 const size_t read_len = 1024; 21 char buf[read_len]; 22 for (;;) { 23 size_t n = fread(buf, 1, read_len, file); 24 result.insert(result.end(), buf, buf + n); 25 if (n < read_len) { 26 break; 27 } 28 } 29 fclose(file); 30 return result; 31 } 另外一种C++风格,但是性能较差的方法:
Aug 20, 2018 · 254 words · 1 min
先放资料:
How to use boost::property_tree to load and write JSON
How to iterate a boost property tree?
不出现key的方法遍历一个json文件:
详细代码 1 /* *********************************************** 2 Author :111qqz 3 mail: renkuanze@sensetime.com 4 Created Time :2018年08月17日 星期五 15时29分23秒 5 File Name :ptree.cpp 6 ************************************************ */ 7 #include <boost/property_tree/ptree.hpp> 8 #include <boost/property_tree/json_parser.hpp> 9 #include <bits/stdc++.h> 10 #include <vector> 11 using namespace std; 12 using boost::property_tree::ptree; 13 14 string indent(int level) { 15 string s; 16 for (int i=0; i<level; i++) s += " "; 17 return s; 18 } 19 20 void printTree (ptree &pt, int level) { 21 if (pt.empty()) { 22 cerr << "\""<< pt.data()<< "\""; 23 } 24 25 else { 26 if (level) cerr << endl; 27 28 cerr << indent(level) << "{" << endl; 29 30 for (ptree::iterator pos = pt.begin(); pos != pt.end();) { 31 cerr << indent(level+1) << "\"" << pos->first << "\": "; 32 33 printTree(pos->second, level + 1); 34 ++pos; 35 if (pos != pt.end()) { 36 cerr << ","; 37 } 38 cerr << endl; 39 } 40 41 cerr << indent(level) << " }"; 42 } 43 44 return; 45 } 46 int main() 47 { 48 ptree root; 49 read_json("terr.json",root); 50 printTree(root,0); 51 52 53 return 0; 54 55 }
Aug 15, 2018 · 525 words · 2 mins
编译某代码,发现报错某函数未定义的引用。该函数的是先前编译得到的动态库中。
先去check了该函数的实现,还有接口与头文件中的声明是否统一。发现没有问题。
然后怀疑.cpp文件没有被编译到,于是在该函数中添加
Jul 19, 2018 · 315 words · 1 min
C++11 std::function 是一种通用、多态的函数封装,它的实例可以对任何可 以调用的目标实体进行存储、复制和调用操作
见下面的例子
1 /* *********************************************** 2 Author :111qqz 3 mail: renkuanze@sensetime.com 4 Created Time :2018年07月19日 星期四 17时41分00秒 5 File Name :bind.cpp 6 ************************************************ */ 7 #include <functional> 8 #include <iostream> 9 using namespace std; 10 float foo( int x,int y,int z){return x+y+z+1.;} 11 int main() 12 { 13 function<int(int,int)>func = foo; 14 int y = 10; 15 function<int(int)>fun = [&]( int value)->int 16 { 17 return 1+value+y; 18 }; 19 cout<<func(15,4,9)<<endl; 20 cout<<fun(8)<<endl; 21 return 0; 22 } std::bind 则是用来绑定函数调用的参数的,它解决的需求是我们有时候可 能并不一定能够一次性获得调用某个函数的全部参数,通过这个函数,我们可以将 部分调用参数提前绑定到函数身上成为一个新的对象,然后在参数齐全后,完成调 用
Jul 10, 2018 · 169 words · 1 min
以前用的办法太老土啦
看到一个since C++11的方法,我觉得比较优雅
1 #include <iostream> 2 #include <chrono> 3 //#include <ratio> 4 #include <thread> 5 6 void f() 7 { 8 std::this_thread::sleep_for(std::chrono::seconds(1)); 9 } 10 11 int main() 12 { 13 auto t1 = std::chrono::high_resolution_clock::now(); 14 f(); 15 auto t2 = std::chrono::high_resolution_clock::now(); 16 17 // floating-point duration: no duration_cast needed 18 std::chrono::duration<double, std::milli> fp_ms = t2 - t1; 19 20 // integral duration: requires duration_cast 21 auto int_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1); 22 23 // converting integral duration to integral duration of shorter divisible time unit: 24 // no duration_cast needed 25 std::chrono::duration<long, std::micro> int_usec = int_ms; 26 27 std::cout << "f() took " << fp_ms.count() << " ms, " 28 << "or " << int_ms.count() << " whole milliseconds " 29 << "(which is " << int_usec.count() << " whole microseconds)" << std::endl; 30 }
Jul 6, 2018 · 235 words · 1 min
用gdb调试c++的时候,需要添加-g编译选项add_compile_options(-g),并且关掉各种编译优化
如果是多线程程序,可以用info threads 查看每个线程的信息
Jul 2, 2018 · 243 words · 1 min
资料推荐这个:MySQL C API programming tutorial
环境为ubuntu 14.04 lts
需要安装mysql 和mysql 开发包
sudo apt-get install libmysqlclient15-dev mysql-server mysql-client
先在mysql 中建立test数据库和test表格
mysql>create database test; mysql>use test; //切换到test数据库中 mysql> create table test(name varchar(255),num int(10) ); //创建一个叫test的表 mysql>show create table test; //显示刚才创建的表信息 mysql> select * from test; //查询test表中数据 mysql>quit 然后用如下cpp代码连接
May 6, 2018 · 1207 words · 3 mins
迫于拙劣的cpp水平,这次来记录一些关于STL算法部分的内容。
参考内容是CS106L的course reader
Iterator Categories # Iterators分为以下五种:
Output Iterators:可以使用 ++;可以用 *myItr = value,不能用 value = *myItr Input Iterators:可以使用 ++;可以用 value = *myItr,不能用 *myItr = value Forward Iterators:可以使用 ++,可以同时用 value = *myItr 和 *myItr = value Bidirectional Iterators:比起 Forward Iterator 多了 --,但是不能 + 或者 += Random-Access Iterators:比起 Bidirectional Iterators 多了 + 和 += Algorithm Naming Conventions # 一些关于STL Algorithm的命名规则
May 4, 2018 · 1543 words · 4 mins
迫于拙劣的cpp水平,来补补以前忽略掉的cpp细节。
老规矩,先放资料。
参考资料:
A Gentle Introduction to C++ IO Streams
“Designing and implementing a general input/output facility for a programming language is notoriously difficult”
Bjarne Stroustrup Stream的基本认识 # 说说我的理解。stream(流)可以看做输入输出的抽象。我们通过流可以忽略掉device的细节,采取同样的输入输出方式。