C++——一些小知识(持续更新)

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系列强大一些,支持多参数构造

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值