Introduction

现代 C 与 C++ 开发基础

C++ 算是一个用户群体比较大的语言了,从 C++98 到 C++11 经历了长达十年多之久的积累,C++14 则是作为对 C++11 的重要补充和优化,所有这些新标准中扩充的特性,给 C++ 这门语言注入了新的活力。

C++1x (C++11/14, 甚至 C++17) 为传统 C++ 注入的大量特性使得整个 C++ 变得更加像一门现代化的语言。C++1x 不仅仅增强了 C++ 语言自身的可用性,auto 关键字语义的修改使得我们更加有信心来操控极度复杂的模板类型。同时还对语言运行期进行了大量的强化,Lambda 表达式的出现让 C++ 具有了几乎在现代的编程语言中已经司空见惯的匿名函数的闭包特性,右值引用的出现解决了 C++ 长期以来被人诟病的临时对象效率问题等等。

C++1x 为自身的标准库增加了非常多的工具和方法,诸如在语言层面上提供了 std::thread 支持了并发编程,在不同平台上不再依赖于系统底层的 API,实现了语言层面的跨平台支持;std::regex 提供了完整的正则表达式支持等等。C++98 已经被实践证明了是一种非常成功的范型,而 C++1x 的出现,则进一步推动这种范型,让 C++ 成为系统程序设计和库开发更好的语言。

C++ 与 C

我们经常在 C++ 中使用一些 C 语言代码(甚至古老的 C 语言代码),例如 Linux 系统调用。在 C++11 出现之前,大部分人当谈及 『C 与 C++ 的区别是什么』时,普遍除了回答面向对象的类特性、泛型编程的模板特性外,就没有其他的看法了,甚至直接回答『差不多』,也是大有人在。下面的韦恩图大致上回答了 C 和 C++ 相关的兼容情况:

C++ 不是 C 的一个超集,在编写 C++ 时,也应该尽可能的避免使用诸如 void* 之类的程序风格。而在不得不使用 C 时,应该注意使用 extern "C" 这种特性,将 C 语言的代码与 C++代码进行分离编译,再统一链接这种做法,例如:

// foo.h
#ifdef __cplusplus
extern "C" {
#endif
int add(int x, int y);
#ifdef __cplusplus
}
#endif
// foo.c
int add(int x, int y) {
reutrn x+y;
}
// main.cpp
#include "foo.h"
int main() {
add(1, 2);
return 0;
}

应先使用 gcc 编译 C 语言的代码:

gcc -c foo.c

编译出 foo.o 文件,再使用 g++ 将 C++代码和 .o 文件链接起来(或者都编译为 .o 再统一链接):

g++ main.cpp foo.o -o main