C++ 学习笔记
String 字符串字符编码格式及其前缀
1 | wchar_t title[] = L"Chief Astrogator"; // w_char string 宽字符 |
UTF-8: 前缀 u8
1 | string a = u8"UTF_8 Encoding"; //UTF-8 char |
Raw String: \ 不再转义, 前缀 R, 使用 () 限界
1 | cout << R"(Jim "King" Tutt uses "\n" instead of endl.)" << '\n'; |
C++ 11 结构体初始化可忽略 =
1 | struct inflatable // structure declaration |
1 | class A |
static 成员变量不属于对象的一部份,而是类别的一部份,所以程序可以在还没有诞生任何对象的时候就处理此种成员变量。但首先你必须初始化它。不要把 static 成员变量的初始化动作安排在类别的构造式中,因为构造式可能一再被调用,而变量的初值却只应该设定一次。也不要把初始化动作安排在头文件中,因为它可能会被包含许多地方,因此也就可能被执行许多次。你应该在实作档中且类别以外的任何位置设定其初值。例如在 main 之中,或全域函数中,或任何函数之外:
1 | double A::rate = 0.0075; // 设立static 成员变量的初值 |
这么做可曾考虑到 m_rate 是个 private 资料?没关系,设定 static 成员变量初值时,不受任何存取权限的束缚。请注意,static 成员变量的型别也出现在初值设定句中,因为这是一个初值设定动作,不是一个数量指定(assignment)动作。事实上,static 成员变量是在这时候(而不是在类别声明中)才定义出来的。如果你没有做这个初始化动作,会产生联结错误:
error LNK2001: unresolved external symbol “private: static double
SavingAccount::m_rate”(?m_rate@SavingAccount@@2HA)
摘自候捷《深入浅出 MFC》
当用于内置类型的变量时,列表初始化有一个重要特点:如果我们使用列表初始化且初始值存在丢失信息的风险,则编译器将报错
1 | long double ld = 3.1415926536; |
——《C++ Primer 5e》P39
如果表达式的内容是解引用操作,则 decltype
将得到引用类型。
1 | int i=42, *p=&i; |
如果 decltype
使用的是一个不加括号的变量,则得到的结果就是该变量的类型;如果给变量加上了一层或多层括号,编译器就会把它当成是一个表达式。变量是一种可以作为赋值语句左传的特殊表达式,所以这样的 decltype
就会得到引用类型。
1 | int i = 42; |
切记: decltype((variable))
(注意是双层括号)的结果永远是引用, 而 decltype(variable)
的结果只有当 variable 本身就是一个引用时才是引用。
——《C++ Primer 5e》P63
当一个算术表达式中既有 `int` 又有无符号数时,那个 `int` 值就会转换成无符号数。
如果一条表达式中已经有了 size()
函数就不要再使用 int
了, 这样可以避免混用 int
和 unsigned
可能带来的问题。
当把 string
对象和字符字面值及字符串字面值混在一条语句中使用时, 必须确保每个加法运算符的两侧的运算对象至少有一个是 string
。
如果容器为空,则 `begin` 和 `end` 返回的是同一个迭代器,都是尾后迭代器。[^note]
[^note]: 测试 markdown 注释语法。
1 | int ia[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; |
p 的类型是由 10 个整数构成的数组;
给指针加上一个整数,得到的新指针仍需指向同一数组的其他元素,或者指向同一数组的尾元素的下一位置
1 | constexpr size_t sz = 5; |
当一个对象被用作右值时,用的是对象的值(内容);当对象被用作左值时,用的是对象的身份(在内存中的位置)。