C++ 进阶必备知识

类定义

  • operator= 注意自我赋值。
  • 对于持有资源的对象,如果不实现“拷贝构造”、“operator=”则注意屏蔽它们(=delete)。
  • 注意经常添加const noexcept override final关键字。
  • 单参数构造函数注意explicit关键字。

初始化

  • 类字段初始化: 就地初始化。
  • POD对象用 POD pod = {}初始化清零。
  • 继承自POD基类的子类,若需要对POD基类清零,需要明确调用POD默认构造 : subClass() : PODbase{} {}  否则会残留脏数据。
  • 一般数组初始化={},字符串初始化可以在构造函数中[0] = '\0'。
  • union字段就地初始化在gcc4中存在bug极有可能忽略构造。

UB(未定义行为: 相同代码片段在不同编译参数或相同编译参数不同情形下表现出不同的非预期结果)

无符号数支持溢出回绕,但有符号数的回绕是UB,gcc需要-fwrapv编译参数才能确保有符号数溢出回绕的正确。

bool变量存储非0或1值时(例如来自malloc假设字节里存储着2),在判断时gcc可能将2视为false

整数类型、转换

  • 8~32位有符号数与uint32的比较,由于类型提升机制负数可能被视为正数从而出错,应当都主动转型为int64再比。
  • 有符号数和uint64的比较,应当先判断有符号数是否为负数再转型为uint64再比较。
  • 时常明确地类型转换,避免编译警告。
  • 循环变量注意回绕,例如 for (uint16_t  i = 0; 【i <= (uint16_t)0xFFFF 】或【 i < (uint16_t)0x10000 】; ++i)都会导致无限循环。

当想要使用std::min函数时,可能受c的min宏干扰,此时  (std::min)(a,b)通过对函数名加括号可以避免被识别为宏

STL

  • string构造参数不能处理(null)
  • for each语法 可以用auto & 处理一般STL容器元素,但vector等元素需要代理的,需要以auto &&来承接。
  • std::string 拷贝构造基于COW,内部有引用; 两个string字段指向同一字符串时,对其一c_str()或data() 强转为char *再修改会导致另一个字段值也被改动; 且多线程会出现问题,多线程应重新构造string(传入指针和大小,而不是传入某个string)。

你可能感兴趣的:(c++,开发语言)