1.尽量使用前置版本的++
2.在大多数用到数组的表达式中,数组被自动转换为指向第一个元素的指针
3.多维数组实际上时数组的数组,所以由多维数组转换的指针实际上是一个指向数组的指针
3.范围for循环记得除了最内层循环,外层循环要用引用(如果只是想访问的话)
4.分配给强制转换是非法的,不支持左值强制转换
5.static_cast不允许常量转换为非常量,而const_cast支持,应当这样写
pv = static_cast<void*>(const_cast<string*>(ps));
6.switch语句尽可能可写一个default分支,即使什么也不做
7.switch语句如果某处一个带有初值的变量位于作用域之外,另一处该变量位于作用域之内,则从前一处跳转到另一处是非法的,要用{}形成语句块。
8.注意*&和&*的区别,前者是指针的引用,后者指引用的指针。
9.initializer_list对象永远是常量
10.C++11允许返回列表
vector<string> func()
{
return {"hello", "nihoa"};
}
11.注意返回数组指针的函数声明格式,或者使用尾置返回类型或者是decltype
string (*func()) [10];
auto func() ->string(*)[10];
string str [10];
decltype(str) * /*or &*/func ();
12.顶层const和非const会导致重载的二义性,但是const &和 &或者底层const和非const不会
13.可使用const_cast将返回值强转成&
14.默认实参只能有一次声明,并且,默认参数后面的参数都必须有默认参数。
15.constexpr函数是指能用于常量表达式的函数,函数体内部只有一条语句——返回一个字面值类型,并且形参也必须是字面值类型;隐式的声明了其为内联函数。
constexpr修饰的变量是一个常量,并且右值只能是常量表达式,不是的话编译器会报错
int main(){ int x = 10; const int a = x; //constexpr b = x; //error constexpr int b = 20; }
constexper函数与之正对应
16.《C++ Primer》P215~P216
17.decltype用于某个函数,返回函数类型,在其后加上一个*即代表了一个函数指针类型
18.返回类型为函数指针的几种表示方法
C++——关于返回类型为函数指针的表达方式_JAN6055的博客-CSDN博客https://blog.csdn.net/JAN6055/article/details/122842612?spm=1001.2014.3001.550219.传递数组的一种方式——可以传递头指针和尾指针
20.可变参数函数
C++——可变参数函数_JAN6055的博客-CSDN博客https://blog.csdn.net/JAN6055/article/details/122843364?spm=1001.2014.3001.550221.对象代码:编译器将我们的源代码转换为对象代码的格式
22.对象文件:编译器根据给定的文件生成保存对象代码的文件,一个或多个对象文件经过链接可生成可执行文件。
23.用const修饰成员函数实际上是修饰的this指针,使this指针从 this const * 变为了const this const *
24.C++11的标准中,最好把类的默认值用类内初始化实现,然后用default声明一个默认的构造函数。
25.如果一个const成员以引用返回一个*this,返回的其实是常量引用,返回值也应写成常量引用
26.如果成员函数定义了cosnt and not const 版本,编译器会根据类是不是常量来自动调用对应版本的函数。
27.共有代码访问私有代码是一种技巧。
28.返回类的引用是一种常用的手段
29.类不允许包含自己,但允许包含自己的引用或者指针,就像链表那样
30.友元只是再类中声明了是友元而已,并不是定义,也不是函数的声明,在定义之前,不能直接在类中调用友元函数
//错误的行为
class A{
public:
friend void test();
void func(){
test();
}
};
void test() {}
31.在类外返回类内成员别忘了用 : : 指明
32.好的习惯,列表初始化成员顺序应当和成员成名顺序一样,尽可能不用其他成员列表初始化其他的成员
33.如果成员是引用,cosnt,或者未提供默认构造函数的其他类,必须使用列表初始化进行赋予初值。
34.如果构造函数的参数列表全提供了默认值,则进而将其作为默认函数代替空实现的构造函数。
35.如果有两个构造函数满足第34条,在不用任何参数创建一个对象时,将会出现二义性
36.true false是bool类型字面值,nullptr也是字面值。
37.在bitbad 被设置时, fail也会被设置,实际上,将流当作判定条件等价的相当于!fail(),eof和bad值对应特定的错误
38.badbir表示系统错误,一般来说badbit被设置之后,流就不能再使用了
39.控制符unitbuf
cout << unitbuf; //每次输出都刷新缓冲区
cout << nounitbuf; //恢复上面的设置
40.虽然拷贝构造和拷贝赋值很像,但是很好区分,只有再新定义一个变量的时候才调用拷贝,即使显式的使用 = ,其余的情况就是拷贝赋值。
41.将构造函数和析构函数声明为inline是没有什么意义的,即编译器并 不真正对声明为inline的构造和析构函数进行内联操作,因为编译器会在构造和析构函数中添加额外的 操作(申请/释放内存,构造/析构对象等),致使构造函数/析构函数并不像看上去的那么精简。其次, class中的函数默认是inline型的,编译器也只是有选择性的inline,将构造函数和析构函数声明为内联 函数是没有什么意义的。
42.因该多使用C++内置的标准库,而不是基本数据类型,像用vector代替数组.
43.通常vector是最好的选择,除非有很好的理由选择其他容器
44.可以使用列表的方式重新赋予容器元素新值
vector<int>vec {1,2,3,4};
vec = {6,2,3};
45.容器的一个函数assign()
i,j为迭代器,n,t为数字,il是initializer_list
(i,j)替换为[i,j)迭代器区间内的值,i,j不能指向自身
(n,t)替换为n个t值
(il)替换为列表中的值
46.swap并未 交换容器的元素,而是交换了两个容器内部的数据结构,因此时间复杂度O(1)
47.特别的对于string为元素容器,指向容器的迭代器、指针、引用会在swap之后失效,不会指向原来的元素,于此相反的其他的数据类型还是指向原来的元素。
48.vector string deque插入元素会使指向其元素,的指针,引用,迭代器失效
49.emplace系列函数是构造元素,可以理解为是push系列函数的构版本,功能稍微比push系列强大一些,支持多参数构造