undefined

一、c++ 中 setw 的用法

setw() 用于控制输出之间的间隔,如下

1
2
3
std::cout << "a" << std::setw(5) << "b" << std::endl;
输出:a b
解释:a 和 b 之间有 4 个空格,上面表达式的意思为 "a" 后面输出 5 个字符,其中 "b" 占一个字符,剩余 4 个字符用空格填充

也可以设置用其他字符填充

1
2
std::cout << "a" << std::setfill('*') << std::setw(5) << "b" << std::endl;
输出:a****b

查看更多

undefined

1
2
3
4
5
6
7
8
9
10
11
12
13
14
std::string MetricUtils::EscapeMetricNameAndTag(const std::string& name) {
if (name.empty() || name.size() > metric::constants::DefaultFieldKeyLengthOfMeasurement) {
return "";
}
std::string output_name(name);
for (size_t index = 0; index < name.size(); index++) {
auto x = name[index];
if (!(x >= '0' && x <= '9') && !(x >= 'A' && x <= 'Z') && !(x >= 'a' && x <= 'z') &&
x != '.' && x != '-' && x != '_') {
output_name[index] = '_';
}
}
return output_name;
}

如上的代码,编译器会优化,其中 output_name 这个字符串会被优化成静态的,即不会每次都创建。

undefined

一、代码检查工具 CppCheck

cppcheck 是c/c++的静态代码检查工具,可以发现代码的静态缺陷,发现代码的逻辑错误,不过他不会检查代码的语法错误

安装:yum install cppcheck

1
2
3
4
5
6
7
8
9
10
cppcheck 是一个静态代码检查工具,支持c, c++ 代码;作为编译器的一种补充检查,cppcheck对产品的源代码执行严格的逻辑检查。 执行的检查包括:
1. 自动变量检查
2. 数组的边界检查
3. class类检查
4. 过期的函数,废弃函数调用检查
5. 异常内存使用,释放检查
6. 内存泄漏检查,主要是通过内存引用指针
7. 操作系统资源释放检查,中断,文件描述符等
8. 异常STL 函数使用检查
9. 代码格式错误,以及性能因素检查

一般使用命令:cppcheck -j 3 –enable=all src (-j 表示工作线程个数,一般工程比较大的时候好用,src 是源代码目录)

查看更多

undefined

C 库函数

一、strtol

原理:丢弃掉任何空白字符,直到找到第一个非空白字符,然后采用尽可能多的字符来形成有效的 base-n 整数表示并将他们转换为一个整数值。有效的整数值由以下部分组成:

  • 可选的。 + 或 -
  • 可选的。 前缀(0)表示八进制基数(仅当 base 基数为 8 或者 0 时)
  • 可选的。前缀(0x 或 0X)表示十六进制基数(仅当 base 基数为 16 或者 0 时)
查看更多

undefined

emplace_back 和 push_back 的区别

push_back 会调用:先调用构造函数,再调用移动构造函数。
或者:先调用构造函数,再调用拷贝构造函数。
push_back 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中。(如果是拷贝的话,事后会自行销毁先前创建的这个元素)

emplace_back 会调用:直接调用构造函数。
emplace_back 则是直接在容器尾部创建这个元素,省去了拷贝或者移动元素的过程

C++中 explicit 关键字

c++ 中 explicit 关键字详解

c++ 中的 explicit 关键字只能用于修饰只有一个参数的类构造函数,他的作用是表明该构造函数是显式的。

与之对应的 implicit 关键字则表明构造函数是隐式的,类构造函数默认情况下即声明为 implicit 隐式的

一、隐式声明的场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class A {
public:
char* str_;
int size_;

A(int size) : size_(size) {
str_ = reinterpret_cast<char*>(malloc(size+1));
memset(str_, 0, size_+1);
}

A(const char* p) {
int size = strlen(p);
str_ = reinterpret_cast<char*>(malloc(size+1));
strcpy(str_, p);
size_ = strlen(str_);
}
};

void test_A() {
A a1(24); // 1. OK,正常用法
A a2 = 10; // 2. OK,发生隐式转换,为 A 预分配 10 字节大小的内存
A a3; // 3. NO,没有默认构造函数
A a4("abc"); // 4. OK,正常用法
A a5 = "abc"; // 5. OK,调用 A(const char*)
A a6 = 'c'; // 6. OK,调用 A(int), 且 size 等于 'c' 的 ASCII 值
a1 = 2; // 7. OK,发生隐式转换,为 A 预分配 2 字节大小的内存
a3 = a1; // 8. 编译正确,但应该重载 = 操作符,正确释放内存
}

如上,表达式 2 中的 A a2 = 10 进行解释,在 C++ 中,如果构造函数只有一个参数时,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型转换为该类对象。

查看更多

extern 关键字

一、extern 的由来

编译器一般采用按文件编译的方式,因此在编译时,各个文件中定义的全局变量是互相不可见的。也就是说,在编译期间,全局变量的可见域限制在文件内部。如下

1
2
3
4
5
6
// a.cpp
int val;
int main() {}

// b.cpp
int val;

编译没有问题,但是链接时会出现问题,重复定义。

在链接阶段,各个文件的内容(编译产生的 obj 文件)是被合并到一起的。因而,定义于某文件内的全局变量,在链接完成后,他的可见范围被扩大到整个程序。

查看更多