源码解读1¶
继承了两个类,copyable
,or nocopyable
。
nocopyable
只需要让其拷贝构造函数和赋值构造函数定义为=delete
即可(c++11特性)或者将其定义为private
。其默认构造函数和析构函数需要定义为protectd
,使得只能为子类使用,但是子类不具有复制行为。
class noncopyable {
public:
noncopyable(const noncopyable&) = delete;
void operator=(const noncopyable&) = delete;
protected:
noncopyable() = default;
~noncopyable() = default;
};
1. TimeStamp
¶
-
PRId64
实现int64
的跨平台
int64
在32/64不同的系统上,表示不同,linux上定义如下:在如下的格式化代码中,通过#if __WORDSIZE == 64 // 64位机器 #define __PRI64_PREFIX "l" #else // 32位机器 #define __PRI64_PREFIX "ll" #endif // 因此在64位的机器上是 ld,32位机器上是lld #define PRId64 __PRI64_PREFIX "d"
PRI64
实现跨平台string Timestamp::toString() const { char buf[32] = {0}; int64_t seconds = microSecondsSinceEpoch_ / kMicroSecondsPerSecond; // 整数 int64_t microseconds = microSecondsSinceEpoch_ % kMicroSecondsPerSecond; // 余数 snprintf(buf, sizeof(buf)-1, "%" PRId64 ".%06" PRId64 "", seconds, microseconds); return buf; }
2.
Atomic
¶
参考atomic.h
文件代码
-
gcc
的原子操作__sydnc_val_compare_and_swap(type* ptr, type oval, type nval)
原子比较交换操作:*ptr* = *ptr==oval? nval : *ptr
。返回的是没有修改过的*ptr
。__sync_fetch_and_add(type* ptr, type value)
原子增加操作:value + x
,并且返回修改之前的value
。线程安全的__sync_lock_test_and_set(type* ptr, type value)
原子赋值操作:*ptr=value
volatile
volatile
关键字是为了确保本指令不会因为编译器的优化而省略,且要求每次直接读值。即:防止编译器对代码进行优化。
当要求使用 volatile
声明的变量的值的时候,系统总是重新从它所在的内存读取数据,而不是使用保存在寄存器中的备份。
-
gcc
编译时选项Wall // 大部分警告 -Wextra // 一些额外的警告 -Werror // 当出现警告时转为错误,停止编译 -Wconversion // 一些可能改变值的隐式转换,给出警告。 -Wno-unused-parameter // 函数中出现未使用的参数,不给出警告。 -Wold-style-cast // C风格的转换,给出警告 -Woverloaded-virtual // 如果函数的声明隐藏住了基类的虚函数,就给出警告。 -Wpointer-arith // 对函数指针或者void *类型的指针进行算术操作时给出警告 -Wshadow // 当一个局部变量遮盖住了另一个局部变量,或者全局变量时,给出警告。 -Wwrite-strings // 规定字符串常量的类型是const char[length],因此,把这样的地址复制给 non-const char *指针将产生警告.这些警告能够帮助你在编译期间发现企图写入字符串常量 的代码 -march=native // 指定cpu体系结构为本地平台
3.
Execption
¶ -
打印
backtrace
信息#include <execinfo.h> int backtrace(void** buffer, int size); char** backtrace_symbols(void* const *buffer, int size);
backtrace
栈回溯,保存各个栈帧的地址buffer
是个指针数组,void* buffer[size]
。- 返回值nptr是实际
buffer
的元素个数,元素是当前进程中活跃的函数。
backtrace_symbols
- 作用
将
backtrace
函数得到的buffer
中的元素(元素是地址)翻译成描述这个地址的字符串。这个字符串组成为:函数名 + 函数的偏移地址 + 16进制的实际的地址,比如:exception_test(_start+0x2a) [0x55661933e5fa]
- 返回值
上面的这个字符串指针数组作为返回值:
char* strings[size]
,size
是函数的传入参数,也即backtrace
的返回值。 - 注意点
这个返回的 **
char* strings[size]
**是这个函数在内部由malloc
分配的内存,因此调用者必须手动free(strings)
。但是buffer
不应该被释放,因为它不是由malloc
分配的。
- 作用
将
demagle
char* abi::__cxa_demangle(const char * mangled_name, char * output_buffer, size_t * length, int * status )
mangled_name
:是一个以\0
结尾的需要被demangle
字符串。output_buffer
:存储结果。如果*length
满足demangled_name
的长度,那么 output_buffer malloc 的长度是*length
,否则就需要调用remalloc
。length
:传入传出参数,传入的是output_buffer
需要分配的大小,如果长度不够,length
就该改变。status
:- 0:
demangle
成功 - -1:内存分配失败
- -2:
mangled_name
无效 - -3:参数列表其中一个无效
- 0:
- 返回值
指向
demangled_name
,或者nullptr
如果返回失败。 调用者需要free
这个内存。