C/C++ 开源库及示例代码
= =
= 说明 =
本页面汇总俺收集的各种 C 和 C++ 的开源代码库,不定期更新。
如果你发现本页面的开源库有错漏之处,非常欢迎给俺提供反馈——有 GitHub 帐号的同学,可以[https://github.com/programthink/opensource/issues 给俺发 issue];没帐号的同学,可以去[http://program-think.blogspot.com/ 俺博客]留言。
—-
= 1 综合性的库 =
Boost
Home:[http://boost.org/]
Links:[https://en.wikipedia.org/wiki/Boost_%28C%2B%2B_libraries%29 Wikipedia] [https://zh.wikipedia.org/wiki/Boost_C%2B%2B_Libraries 维基百科]
Boost 大概是最重要的第三方 C++ 库。其作者有很多是 C++ 标准委员会的成员。Boost 的很多子库后来都成为 C++ 的标准库。
本页面的其它章节还会继续提及 Boost 在各种领域的应用。
wxWidgets
Home:[https://wxwidgets.org/]
Links:[https://en.wikipedia.org/wiki/WxWidgets Wikipedia] [https://zh.wikipedia.org/wiki/WxWidgets 维基百科]
这是一个非常老牌的 C++ 开源 GUI 框架,诞生于1992年。原先叫做 wxWindows,后来因为微软的法律纠纷,改为现名。
它支持的操作系统平台很多(包括嵌入式系统)。
很多开源项目用到它,比如:BitTorrent、aMule、FileZilla、Code::Blocks、Dolphin……
虽然它以 GUI 为主,但是也提供了其它一些辅助功能(比如:进程间通讯、网络、数据库、多媒体……)
Qt
Home:[http://www.qt-project.org/]
Links:[https://en.wikipedia.org/wiki/Qt_(toolkit) Wikipedia] [https://zh.wikipedia.org/wiki/Qt 维基百科]
这是一个非常老牌的 C++ 开源 GUI 框架,于1995年发布 1.0 版本。原先由 Trolltech 公司维护,后来该公司被 Nokia 收购。
它支持的操作系统平台很多(包括嵌入式系统)。
虽然它以 GUI 为主,但是也提供了其它一些辅助功能(比如:网络、数据库、多媒体、3D引擎……)
APR(Apache Portable Runtime)
Home:[https://apr.apache.org/]
Links:[https://en.wikipedia.org/wiki/Apache_Portable_Runtime Wikipedia] [https://zh.wikipedia.org/wiki/Apache%E5%8F%AF%E7%A7%BB%E6%A4%8D%E8%BF%90%E8%A1%8C%E6%97%B6 维基百科]
这是由 Apache 社区维护的 C 开源库,主要提供操作系统相关的功能(文件系统、进程、线程、用户、IPC)。此外还提供了一些网络相关的功能。
APR 原先是 Apache Web 服务器的一个组成部分,后来独立出来,成为一个单独的开源项目。
ACE(Adaptive Communication Environment)
Home:[http://www.cse.wustl.edu/~schmidt/ACE.html]
Links:[https://en.wikipedia.org/wiki/Adaptive_Communication_Environment Wikipedia] [https://zh.wikipedia.org/wiki/ACE%E8%87%AA%E9%80%82%E9%85%8D%E9%80%9A%E4%BF%A1%E7%8E%AF%E5%A2%83 维基百科]
这是一个跨平台的 C++ 库,提供了一套网络通讯的框架;另外还支持线程、进程和 IPC。
POCO
Home:[http://pocoproject.org/]
Links:[https://en.wikipedia.org/wiki/POCO_C%2B%2B_Libraries Wikipedia]
它的名称源自“POrtable COmponents”,是一个基于 C++ 的开源库。
它的功能以网络通讯为主,同时也提供一些其它功能(比如:多线程、进程间通讯、数据库、XML、JSON……)
Dlib
Home:[http://dlib.net/]
Links:[https://en.wikipedia.org/wiki/Dlib Wikipedia]
诞生于2002年的 C++ 开源库,提供了非常多的功能(网络、多线程、GUI、数值计算、图像处理、数据挖掘……)。
它还有一个特色是:同时提供了 Python API
Crypto++
Home:[http://www.cryptopp.com/]
Links:[https://en.wikipedia.org/wiki/Crypto%2B%2B Wikipedia]
它也叫“CryptoPP”或“libcrypto++”,是非常著名的开源加密库,诞生于1995年。基于 C++ 开发,大量用到模板语法。
虽然它以加密为主,但是也提供了其它一些辅助功能(比如:数据压缩、编码解码、计时器…)
—-
= 2 数据结构 & 算法 =
== 2.1 容器 ==
=== 2.1.1 标准容器 ===
std
C++ 98 标准内置的 STL 提供了如下容器:
* 数组:vector(动态数组)、valarray(针对数值类型特化的 vector)、bitset(储存比特的【固定】数组)
* 链表:list(双向)
* 队列:queue、deque(双端队列)
* 栈:stack
* 映射:map(键值无重复)、multimap(键值可重复)
* 集合:set(元素无重复)、multiset(元素可重复)
[https://en.wikipedia.org/wiki/C%2B%2B11 C++ 11 标准]新增了如下容器:
* 数组:array(相比 vector,它的 size 是编译时【固定】的)
* 链表:forward_list(相比 list,它是【单向】的)
* 映射:unordered_map、unordered_multimap(相比 map 和 multimap,这俩采用 hash 实现)
* 集合:unordered_set、unordered_multiset(相比 set 和 multiset,这俩采用 hash 实现)
下面几个容器,C++ 标准【没有】包含,但包含在某些知名的 STL 第三方库中(比如 SGI 的 STL):
* 映射:hash_map、hash_multimap(与 unordered_map、unordered_multimap 相同)
* 集合:hash_set、hash_multiset(与 unordered_set、unordered_multiset 相同)
=== 2.1.2 Lockfree 的容器 ===
(“lock-free”翻译成“锁无关”会引发歧义,所以俺直接用洋文)
Boost.Lockfree
Docs:[http://boost.org/libs/lockfree]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了三种 lock-free 的容器(queue、stack、spsc_queue)。最后这种是“环形缓冲”。
libcds(Concurrent Data Structures)
Home:[http://libcds.sourceforge.net/]
这是一个跨平台的 C++ 开源库,提供了若干 lock-free 的容器。它的 2.0.0 版本,代码重写以支持 C++ 11 标准。
=== 2.1.3 环形缓冲 ===
Boost.CircularBuffer
Docs:[http://boost.org/libs/circular_buffer]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“环形缓冲区”的模板。
“环形缓冲区”可以降低内存分配的开销。俺曾经写过一篇博文推荐环形缓冲区(在“[http://program-think.blogspot.com/2009/04/producer-consumer-pattern-3-circle.html 这里]”)。
代码示例
boost::circular_buffer
cb.push_back(1);
cb.push_back(2);
cb.push_back(3);
// The buffer is full now
// pushing subsequent elements will overwrite front-most elements.
cb.push_back(4); // Overwrite 1 with 4.
cb.push_back(5); // Overwrite 2 with 5.
// The buffer now contains 3, 4 and 5.
// Elements can be popped from either the front or the back.
cb.pop_back(); // 5 is removed.
cb.pop_front(); // 3 is removed.
// Leaving only one element with value = 4.
assert(cb[0] == 4);
=== 2.1.4 多维数组 ===
Boost.MultiArray
Docs:[http://boost.org/libs/multi_array]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了任意维的数组。
代码示例——3维数组
typedef boost::multi_array
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);
int values = 0;
for(index i=0; i!=3; ++i)
for(index j=0; j!=4; ++j)
for(index k=0; k!=2; ++k)
A[i][j][k] = values++;
=== 2.1.5 图 ===
Boost.Graph
Docs:[http://boost.org/libs/graph]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,简称 BGL(Boost Graph Library),封装了“图”这种数据结构。
它提供了与 STL 类似的泛型编程风格。
Dlib
Docs:[http://dlib.net/graph_tools.html]
Dlib 前面已经介绍过。它提供了2个类(graph & directed_graph)封装“图”。
== 2.2 对容器的操作 ==
(STL 标准库里面已经实现了很多算法用来操作容器,考虑到本页面已经很长,这里只列举第三方库实现的算法)
Boost.Foreach
Docs:[http://boost.org/libs/foreach]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了通用的遍历,其效果类似于 Python 的 for 循环语法。
有了它,你在遍历时无需声明迭代器变量,也无需关心遍历的容器是何种类型。
代码示例——遍历字符串
std::string test(“Hello, world!”); // string 可以视为 char 的容器
BOOST_FOREACH(char ch, test)
{
std::cout << ch;}
== 2.3 字符串处理 ==
=== 2.3.1 字符集 ===
Boost.Locale
Docs:[http://boost.org/libs/locale]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了各种“本地化”的功能。其中就包括字符集编码转换。
代码示例
using namespace boost::locale;
std::locale loc = generator().generate(“he_IL.UTF-8”);
std::wofstream file.
file.imbue(loc);
file.open(“hello.txt”);
file << L"שלום!";
POCO.Text
Docs:[http://pocoproject.org/docs/package-Foundation.Text.html]
POCO 前面已经介绍过。它提供了 UTF8/UTF16/UTF32 的转换。
=== 2.3.2 字符串格式化 ===
Boost.Format
Docs:[http://boost.org/libs/format]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“格式化字符串”的功能。相比 ANSI C 的 sprintf() 和 snprintf(),它的格式化功能更强并且更安全。
代码示例
using std::cout;
using boost::format;
// 基于“位置指示符”的格式串语法
cout << format("%1% %2% %3% %2% %1%") % "11" % "22" % "333";// 输出如下:// 11 22 333 22 11// 兼容 printf() 的格式串语法cout << format("%s %d") % "price" % 1234;// 输出如下:// price 1234
fmt
Home:[https://github.com/fmtlib/fmt]
这是一个轻量级、类型安全、高性能的字符串格式化库。它也可以用来替代 C++ 标准库中的 IOStreams。
代码示例
// 使用 Python 的格式化语法
fmt::print(“Hello, {}!”, “world”);
// 使用 printf 的格式化语法
fmt::printf(“Hello, %s!”, “world”);
// 使用序号参数,
std::string s = fmt::format(“{0} {1} {0}”, “Hello”, “world”);
// 使用命名参数
fmt::print(“Hello, {name}! The answer is {number}. Goodbye, {name}.”,
fmt::arg(“name”, “World”), fmt::arg(“number”, 42));
=== 2.3.3 正则表达式 ===
PCRE(Perl Compatible Regular Expressions)
Home:[http://www.pcre.org/]
Links:[https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions Wikipedia]
这是一个很老牌的正则表达式的库,诞生于1997年。很多知名的开源项目(Apache、PHP、KDE)用到了它。
Boost.Regex
Docs:[http://boost.org/libs/regex]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“正则式”的功能。
注:Boost 的这个子库已经进入 C++ 11 标准。
代码示例——基于正则式进行匹配和替换
using std::string;
using namespace boost;
// 正则式匹配的例子
bool validate_card_format(const string& s)
{
const regex e(“(\\d{4}[- ]){3}\\d{4}”);
return regex_match(s, e);
}
// 正则式替换的例子
const regex e(“\\A(\\d{3,4})[- ]?(\\d{4})[- ]?(\\d{4})[- ]?(\\d{4})\\z”);
const string machine_format(“\\1\\2\\3\\4”);
const string human_format(“\\1-\\2-\\3-\\4”);
string machine_readable_card_number(const string& s)
{
return regex_replace(s, e, machine_format, match_default|format_sed);
}
string human_readable_card_number(const string& s)
{
return regex_replace(s, e, human_format, match_default|format_sed);
}
re2
Home:[https://github.com/google/re2]
这是 Google 提供的正则式库,基于 C++。其 API 使用起来很简洁。
有多种脚本语言(Python、Ruby、Perl、Node.js、Erlang、OCaml)提供了对它的封装。
代码示例——基于正则式进行匹配
int i;
string s;
assert(RE2::FullMatch(“test:1234”, “(\\w+):(\\d+)”, &s, &i));
assert(s == “test”);
assert(i == 1234);
Oniguruma(鬼车)
Home:[http://www.geocities.jp/kosako3/oniguruma/]
Links:[https://en.wikipedia.org/wiki/Oniguruma Wikipedia]
来自日本的正则式库,基于 C 语言。据说性能很高。
它被用在 Ruby、TextMate、Sublime Text、SubEthaEdit 等软件上。
POCO.RegExp
Docs:[http://pocoproject.org/docs/package-Foundation.RegExp.html]
POCO 前面已经介绍过。它提供了正则表达式的封装类。
Qt.QRegExp
Docs:[http://doc.qt.io/qt-4.8/qregexp.html]
Qt 前面已经介绍过。这是 Qt 中的一个类,提供了“正则式”的功能。
=== 2.3.4 (其它) ===
Boost.StringAlgorithms
Docs:[http://boost.org/libs/algorithm/string]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了各种字符串的算法(替换、合并、拆分、大小写转换、trim……)。
代码示例——字符串合并
std::vector
// 此处填充 v
std::cout << boost::algorithm::join(v, " ") << '\n';
Boost.Lexical_Cast
Docs:[http://boost.org/libs/lexical_cast]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了各种字符串与其它类型的转换。
注:Boost 的这个子库已经进入 C++ 11 标准。
代码示例
std::string s = boost::lexical_cast
std::cout << s << '\n';double d = boost::lexical_cast
std::cout << d << '\n';
== 2.4 内存相关 ==
=== 2.4.1 智能指针 ===
Boost.SmartPointers
Docs:[http://boost.org/libs/smart_ptr]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了几种智能指针。最常用的是“shared_ptr”。
有了智能指针,你就无需操心 new 之后的 delete 了。
注:Boost 的这个子库已经进入 C++ 11 标准。
=== 2.4.2 内存池 ===
Boost.Pool
Docs:[http://boost.org/libs/pool]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“内存池”的功能。
Dlib
Docs:[http://dlib.net/other.html]
Dlib 前面已经介绍过。它提供了内存池(参见文档中以“memory_manager”开头的类)。
APR
Docs:[https://apr.apache.org/docs/apr/trunk/modules.html]
APR 前面已经介绍过。它提供了内存池的功能。
== 2.5 时间 & 日期 ==
Boost.Date_Time
Docs:[http://boost.org/libs/date_time]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了针对“日期 和 时间”的各种处理。
POCO.DateTime
Docs:[http://pocoproject.org/docs/package-Foundation.DateTime.html]
POCO 前面已经介绍过。它提供了若干个日期和时间的封装类(时区转换、格式化字符串、解析时间字符串)。
== 2.6 编码 & 解码 ==
=== 2.6.1 序列化 ===
Boost.Serialization
Docs:[http://boost.org/libs/serialization]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了【可定制的】“序列化”功能。
=== 2.6.2 Base64 ===
[https://en.wikipedia.org/wiki/Base64 Base64] 是一组编码算法的总称。用于把二进制数据编码为文本。
Boost.Serialization
Docs:[http://boost.org/libs/serialization]
Boost 前面已经介绍过。使用前面提到的“Boost.Serialization”,你可以定制采用 Base64 方式进行编码和解码。
Crypto++
Docs:[http://www.cryptopp.com/docs/ref/annotated.html]
Crypto++ 前面已经介绍过。它提供了6个类,分别用于 Base64、Base32、Base16 的编码/解码。
POCO.Streams
Docs:[http://pocoproject.org/docs/package-Foundation.Streams.html]
POCO 前面已经介绍过。它提供了 Base64 和 Base32 的编码/解码。
== 2.7 (其它) ==
=== 2.7.1 随机数 ===
std
ANSI C 在 stdlib.h 中提供了随机数生成函数 rand()。使用前记得先用 srand() 函数播种,否则就傻了。
Boost.Random
Docs:[http://boost.org/libs/random]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“随机数生成”的功能。
相比 ANSI C 的随机数函数,它提供的功能更丰富。
代码示例
double SampleNormal(double mean, double sigma)
{
using namespace boost;
// 建立一个 Mersenne twister 随机数产生器,使用当前时间播种
static mt19937 rng(static_cast
// 选择高斯机率分布
normal_distribution
// 使用 function 的形式,生成随机数据产生器
variate_generator
// 传回样本分布结果
return normal_sampler();
}
Crypto++
Docs:[http://www.cryptopp.com/docs/ref/class_random_number_generator.html]
Crypto++ 前面已经介绍过。它提供了好几个类,用于随机数生成。
=== 2.7.2 UUID ===
Boost.UUID
Docs:[http://boost.org/libs/uuid]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了 UUID 的生成。
代码示例——生成 UUID
// uuid 类以 POD 方式实现,可以直接用在 memcpy()
unsigned char uuid_data[16];
boost::uuids::uuid u;
memcpy(&u, uuid_data, 16);
APR
Docs:[https://apr.apache.org/docs/apr/trunk/modules.html]
APR 前面已经介绍过。它提供了 UUID 的生成、格式化成字符串、解析 UUID 字符串。
POCO.UUID
Docs:[http://pocoproject.org/docs/package-Foundation.UUID.html]
POCO 前面已经介绍过。它提供了 UUID 的生成、格式转换。
—-
= 3 编程范式 =
(这一章节主要针对 C++——“支持多范式”是 C++ 的一大特色)
== 3.1 面向对象编程(OOP) ==
fruit
Home:[https://github.com/google/fruit]
它是 Google 开发的 C++ 库,提供了“依赖注入”([https://en.wikipedia.org/wiki/Dependency_injection dependency injection])的框架。
代码示例——一个简单的例子
using fruit::Component;
using fruit::Injector;
class Writer
{
public:
virtual void write(std::string str) = 0;
};
class StdoutWriter : public Writer
{
public:
// Like “StdoutWriter() = default;” but also marks this constructor as the
// one to use for injection.
INJECT(StdoutWriter()) = default;
virtual void write(std::string str) override
{
std::cout << str; }};class Greeter{public: virtual void greet() = 0;};class GreeterImpl : public Greeter{private: Writer* writer;public: // Like "GreeterImpl(Writer* writer) {...}" // but also marks this constructor as the one to use for injection. INJECT(GreeterImpl(Writer* writer)) : writer(writer) { } virtual void greet() override { writer->write(“Hello world!\n”);
}
};
Component
{
return fruit::createComponent()
.bind
.bind
}
int main()
{
Injector
Greeter* greeter = injector.get
greeter->greet();
return 0;
}
== 3.2 泛型编程(GP) ==
Boost.TypeTraits
Docs:[http://boost.org/libs/type_traits]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“类型特化”相关的辅助功能。
== 3.3 函数式编程(FP) ==
(不了解“函数式编程”的同学,可以先看[https://zh.wikipedia.org/wiki/%E5%87%BD%E6%95%B8%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80 维基百科])
Boost.Function
Docs:[http://boost.org/libs/function]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,用来辅助封装函数对象(仿函式)。
注:Boost 的这个子库已经进入 C++ 11 标准。
代码示例——封装标准 C 的函数
using namespace std;
boost::function
cout << f("42") << '\n';f = strlen;cout << f("42") << '\n';
Boost.Lambda
Docs:[http://boost.org/libs/lambda]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“匿名函数/无名函数”的功能。
注:Boost 的这个子库已经进入 C++ 11 标准。
代码示例
using namespace std;
vector
// 此处填充 v
for_each(v.begin(), v.end(), cout << boost::lambda::_1 << "\n");
== 3.4 元编程(Metaprogramming) ==
(不知道何为“元编程”,可以先看[https://zh.wikipedia.org/wiki/%E5%85%83%E7%BC%96%E7%A8%8B 维基百科])
Boost.MPL
Docs:[http://boost.org/libs/mpl]
Boost 前面已经介绍过。这是 Boost 的其中一个子库,提供了“模板元编程”的框架。
Dlib
Docs:[http://dlib.net/metaprogramming.html]
Dlib 前面已经介绍过。它提供了“模板元编程”的辅助类。
—-