C++ Core Guidelines 笔记01

CppCoreGuidelines

由C++原作者发起的一个modern C++ guidelilne. 在这里,配套的github页面在这里。

CppCoreGuidelines 配套一组 Guideline Support Library,源码位于这里。

我只记录了对自己有启发的内容。笔记中的大部分代码片段是复制于原文,我自己增加的代码片段会标注清楚。

P.1 Express ideas directly in code.

class Date {
public:
    Month month() const;  // do
    int month();          // don't
    // ...
};

所以,推荐的做法是利用type对所有可能的概念进行建模。例如不用一个primitive类型int来表示月份,而用一个专门的Month类。但是这样做需要实现Month的一些运算用的接口,例如加法,减法。

change_speed(Speed s);    // better: the meaning of s is specified
// ...
change_speed(2.3);        // error: no unit
change_speed(23m / 10s);  // meters per second

这里推荐我们实际使用value literal,也就是像23m,10s一样的实现。

P.1 tips

使用gsl::index而不是int

P.3 Express intent

我理解的是在一段scope的开始,或者开始阶段,最好能够尽可能的指明接下来一段scope要进行的事。
不推荐的示例->

gsl::index i = 0;
while (i < v.size()) {
    // ... do something with v[i] ...
}

原文认为i在scope外,没有必要。只看while的开头部分,没有对接下来要发生的循环提供更多信息。循环是为了做和v无关的事,还是要访问v,修改v?下面的代码有略微清楚的intent:我们要访问v中的所有元素,但不修改这些元素。
推荐的示例->

for (const auto& x : v) { /* do something with the value of x */ }

也可以尝试使用for_each

对于参数列表,有点类似于 P.1 ,定义专门的类。

draw_line(int, int, int, int);  // obscure
draw_line(Point, Point);        // clearer

原文强调,如果发生如下情况,很可能是函数设计的不够好。
functions with many parameters of built-in types

P3 and P5 tips

使用gsl中的span来代替指针和size的组合。

void read(span<int> r); // read into the range of integers r

int a[100];
read(a);        // better: let the compiler figure out the number of elements

P.6 What cannot be checked at compile time should be checkable at run time

extern void f4(vector<int>&);   // separately compiled, possibly dynamically loaded
extern void f4(span<int>);      // separately compiled, possibly dynamically loaded
                                // NB: this assumes the calling code is ABI-compatible, using a
                                // compatible C++ compiler and the same stdlib implementation

void g3(int n)
{
    vector<int> v(n);
    f4(v);                     // pass a reference, retain ownership
    f4(span<int>{v});          // pass a view, retain ownership
}

原文说上述示例至少让f4有check范围(size or boundness)的可能。
下面代码是两个例子拼成的。

void increment2(span<int> p)
{
    for (int& x : p) ++x;
}

void use3(int m)
{
    const int n = 10;
    int a[n] = {};
    // ...
    increment2(a);   // the number of elements of a need not be repeated
    // ...
}

此时increment2有能力进行范围检查,use3不会因为混淆n和m造成问题。

P.9 Don’t waste time or space

这里的示例没有解释特别细致。我理解到的指导意见是需要local copy时,尽量不要使用new delete pair,这在其他guideline里也有提到。但是这并不是因为效率问题,应该是为了防止leak。原文提到了struct内部变量声明的次序会引起空间浪费,这个在以前看到过但是并不记得正确的处理方法,一下也查不到其他guideline。

不要像下述代码片段一样在for循环中使用类似size()的函数除非size()真的会返回变化的数值。

void lower(zstring s)
{
    for (int i = 0; i < strlen(s); ++i) s[i] = tolower(s[i]);
}

你可能感兴趣的:(c++,学习笔记,c++)