CppCoreGuidelines P.11 通过封装整理混乱代码
04 January 2022
P.11: Encapsulate messy constructs, rather than spreading through the code
理由
代码散乱既难维护又容易隐藏 bug。尽量通过接口封装代码,好的接口易用有安全。
例子
int sz = 10; int* p = (int*) malloc(sizeof(int) * sz); int count = 0; int input_max = 20; int input_val = 0; for (;;) { int x = input_val++; if (input_val > input_max) break; if (count == sz) p = (int*) realloc(p, sizeof(int) * sz * 2); p[count++] = x; } for (int i=0; i<count; i++) cout << p[i] << " ";
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
上面的代码进行底层内存操作、繁琐又容易出错。此处可以使用 vector
:
vector<int> v; v.reserve(100); int input_max = 20; int input_val = 0; for (;;) { int x = input_val++; if (input_val > input_max) break; v.push_back(x); } std::ranges::for_each(v, [](const auto &x){cout << x << " ";});
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
注意
标准库和 GSL 是符合本条原则指南的。比如,为了避免数组、联合体、类型转换等诡异的生命周期管理。gsl::owner
等工具可以实现关键的抽象机制,比如
vector
, span
, lock_guard
, future
等。我们应该使用那些由更专业的时间花费大量时间开发的程序库。同样的,我们应当设计实现更多专业的程序库给用户使用,而不是让他们(很多时候是我们自己)重复的处理底层代码。
强化
- 检查“混乱的代码”,比如复杂的指针操作、抽象实现之外的类型转换。