求职之C++小知识点整理

1.顺序容器

1.顺序容器:vector,deque,list,forward_list,array,string。其中除list和forward_list外,其它都支持快速随机访问。
     deque <int> a = { 1, 2, 3, 4, 5, 6 };
        cout << a [ 4 ] << endl ;

2.通常使用vector
   forward_list和list的额外内存开销很大。

3.若容器的元素类型没有默认构造函数,在使用容器大小参数构造顺序容器时,必须提供一个元素初始化器。(P294-P295)

4. reverse_iterator 按逆序寻址元素的迭代器

5.迭代器范围:标准库的基础
  包含两个迭代器,元素范围是[begin,end)

6.只有顺序容器(array除外)的构造函数才能接受大小参数

7. 顺序容器assign操作(array不支持assign)
用参数指定的元素的拷贝替换左边容器的所有元素——相当于左边容器清空后再用右边指定元素赋值。
a.assign(b);
a.assign(iter1,iter2);   某个容器的两个迭代器
a.assign(n,t);  //a的size变成n,每个元素都设为t。
assign会使迭代器,指针和引用失效

8.swap   两个swap的容器要相同类型  (array的类型包括元素类型和size)
除array外:swap不对任何元素拷贝,删除,插入,移动等操作。   仅交换了容器的名字。O(1)时间复杂度。
array:swap会交换元素,O(n)时间复杂度。
array和string的迭代器,指针和引用会失效。其他容器则不会。


2.指针问题

  1. char *c[] = { "ENTER""NEW""POINT""FIRST" };   
  2. char **cp[] = { c+3, c+2, c+1, c };   
  3. char ***cpp = cp;   
  4.   
  5.   
  6. int main(void)  
  7. {   
  8.     printf("%s", **++cpp);   
  9.     printf("%s", *--*++cpp+3);   
  10.     printf("%s", *cpp[-2]+3);   
  11.     printf("%s\n", cpp[-1][-1]+1);   
  12.     return 0;  
  13. }  



3.右值引用

左值和右值:
左值是表达式结束后依然存在的持久对象。
右值是表达式结束时就不再存在的临时对象。

区分左值右值的快捷方法:看能不能对表达式取值,如果能是左值,不能则是右值。

左值引用:
分为非常量左值引用和常量左值引用
非常量左值只能绑定到非常量左值,不能绑定到常量左值,非常量右值和常量右值。
常量左值引用可以绑定到所有类型的值,包括非常量左值,常量左值,非常量右值和常量右值

右值引用:
非常量右值:只能绑定到非常量右值,不能绑定到非常量左值、常量左值和常量右值。
常量右值:可以绑定到非常量右值和常量右值,不能绑定到非常量左值和常量左值。

如果提供了move版本的构造函数,就不会生成默认构造函数。
编译器永远不会自动生成move版本的构造函数和复制函数,需要手动显示添加。
选择构造和赋值的重载函数优先级顺序:
1.常量值只能绑定到常量引用上,不能绑定到非常量引用上。
2.左值优先绑定到左值引用上,右值优先绑定到右值引用上。
2.非常量值优先绑定到非常量引用上。

在move版本的构造函数或赋值函数内部,都直接移动了其内部数据的指针(因为它是非常量右值,是一个临时对象,移动了其内部数据的指针不会导致任何问题,它马上就要被销毁了,我们只是重复利用了其内存 ),这样节省了拷贝数据的大量开销。

右值引用是用来支持转移语义的。转移语义可以将资源 ( 堆,系统对象等 ) 从一个对象转移到另一个对象,这样能够减少不必要的临时对象的创建、拷贝以及销毁,能够大幅度提高 C++ 应用程序的性能。临时对象的维护 ( 创建和销毁 ) 对性能有严重影响。

转移语义是和拷贝语义相对的,可以类比文件的剪切拷贝,当我们将文件从一个目录拷贝到另一个目录时,速度比剪切慢很多。

通过转移语义,临时对象中的资源能够转移其它的对象里。

转移构造函数:

1. 参数(右值)的符号必须是右值引用符号,即“&&”。

2. 参数(右值)不可以是常量,因为我们需要修改右值。

3. 参数(右值)的资源链接和标记必须修改。否则,右值的析构函数就会释放资源。转移到新对象的资源也就无效了。

标准库函数std::move
编译器只对右值引用才能调用转移构造函数和转移赋值函数。而所有命名空间都只能是左值引用。
std::move用来将左值引用转换为右值引用

精确传递perfect forwarding
将一组参数原封不动的转递给另一个函数
原封不动是指:参数值不变,还有左值/右值,const/not-const属性都不变。

接受一个右值引用的参数,就能够将所有的参数类型原封不动的传递给目标函数。

们在设计类的时候如果有动态申请的资源,也应该设计转移构造函数和转移拷贝函数。在设计类库时,还应该考虑 std::move 的使用场景并积极使用它

4.拷贝构造函数、析构函数

定义一个类是,要显示或者隐式的指定该类型的对象拷贝、移动、赋值和销毁时做什么。

拷贝构造函数的第一个参数必须是一个引用类型:如果不是引用类型,则调用永远不会成功。因为想要调用拷贝构造函数,必须拷贝实参,单位了拷贝实参,有需要调用拷贝构造函数,无限循环。

即使定义了其他构造函数,编译器默认生成合成拷贝构造函数。

explicit:抑制狗杂函数的隐式转换。

重载运算符本质上是函数,起名字由operator关键字后接表示要定义的运算符的符号组成。
赋值运算符通常返回一个指向其左侧运算对象的引用。

析构函数:释放对象使用资源,销毁对象的非static数据成员。
不接受参数,不能被重载,一个给定类只有一个析构函数。

当指向一个对象的引用或指针离开作用域时,析构函数不会执行。

需要析构函数的类也需要拷贝和赋值操作
需要拷贝操作的类也需要赋值操作,需要赋值操作的类也需要拷贝操作
但需要拷贝构造函数或需要拷贝赋值运算符的类 不意味着也需要析构函数。

当累的程艳中有指针类型,需要在析构函数中显示delete来释放空间,并且拷贝构造函数和拷贝赋值运算符要求深拷贝而不是浅拷贝。

=default修饰成员声明,显示要求编译器生成合成的版本。
类内用=default表示合成的函数隐式声明为内联
类外用=default表示何晨固定成员不是内联函数

5.内存溢出、内存泄漏

内存泄漏最终会导致内存溢出
内存溢出:申请了一个int却存放了一个long long
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值