CPP0309

263 阅读4分钟

unordered_map

1 unordered_map 底层是hashtable, 每个key 都通过特定的哈希运算映射到特定的位置。

2 因为不同的key 值哈希运算后可能结果相同,所以hashtable可能存在冲突。解决方法是每个位置放一个桶,用于存放映射到此位置的元素,当桶内元素小于8 时用链表来实现,大于8时用红黑树。

image.png

补充问:为什么是8 黑树的查找时间的平均复杂度为log n,而链表为n/2,8是一个分割点

3 unordermap始终比map内存空间占用量大些,而且是成线性比例的。

4 使用场景:有序,查询速度稳定,容器元素量少于1000的非频繁查询用map ,若非常高频查询,内部元素可非有序,数据大超过1k甚至几十万上百万时候频繁查询用hash_map。

stl::map对于与java中的TreeMap,而boost::unordered_map对应于java中的HashMap。

5 用法:

用法的区别就是,stl::map 的key需要定义operator< 。 而boost::unordered_map需要定义hash_value函数并且重载operator==。对于内置类型,如string,这些都不用操心。对于自定义的类型做key,就需要自己重载operator< 或者hash_value()了。

重置的例子:

blog.csdn.net/orzlzro/art…

静态变量

static 变量 是静态变量,存储在静态存储区,整个程序期间始终存在。

全局静态变量作用域从定义到文件结束

局部静态变量作用域为局部作用域,变量离开作用域后没有被销毁,仍然存在内存中,只是不能被访问。

静态函数

static + 函数 被定义为静态函数。

warning:不要在头文件中声明static的全局函数,不要在cpp内声明非static的全局函数,如果你要在多个cpp中复用该函数,就把他的声明提到头文件中去,否则cpp内声明需加上static修饰。

类的静态成员

静态成员可以实现多个对象之间的数据共享,类中的所有对象都可以使用它。

类的静态函数

对静态成员函数的引用不需要对象名。静态成员函数的实现不能直接引用类中的非静态成员,可以引用类中的静态成员。

C++和C的区别

设计思想上:

C++是面向对象的语言,而C是面向过程的结构化编程语言

语法上:

C++具有封装、继承和多态三种特性

C++和C相比,增加许多多类型安全的功能,比如强制类型转换

C++支持范式编程,比如模板类、函数模板等

C++中四种cast转换(没用过)

四种类型转换是:static_cast,dynamic_cast,const_cast,reinterpret_cast

1、const_cast

用于将const变量转化为非const

2、static_cast

用于各种隐式转换,比如非const转const,void转指针等,static_cast能用于多态向上转化,如果向下转能成功但是不安全,结果未知。

3、dynamic_cast

用于动态类型的转换。只能用于含有虚函数的类,用于类层次间的向上和向下转化。只能转指针或引用。向下转化时,如果是非法的对于指针返回NULL,对于引用抛异常。要深入了解内部转换的原理。

向上转换:指的是子类向基类的转换

向下转换:指的是基类向子类的转换

它通过判断在执行到该语句的时候变量的运行时类型和要转换的类型是否相同来判断是否能够进行向下转换。

4、reinterpret_cast

几乎什么都可以转,比如将int转指针,可能会出问题,尽量少用;

5、为什么不使用C的强制转换?

C的强制转换表面上看起来功能强大什么都能转,但是转化不够明确,不能进行错误检查,容易出错。

C++中指针与引用的区别

1.指针有自己的一块空间,而引用只是一个别名;

2.使用sizeof看一个指针的大小是4,而引用则是被引用对象的大小;

3.指针可以被初始化为NULL,而引用必须被初始化且必须是一个已有对象 的引用;

4.作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引用的修改都会改变引用所指向的对象;

5.可以有const指针,但是没有const引用;

6.指针在使用中可以指向其它对象,但是引用只能是一个对象的引用,不能 被改变;

7.指针可以有多级指针(**p),而引用至于一级;

8.指针和引用使用++运算符的意义不一样;

9.如果返回动态内存分配的对象或者内存,必须使用指针,引用可能引起内存泄露。

external 关键字

只在头文件中通过extern给出全局变量的声明(即external int a; 而不要写成external int a = 1;),并在源文件中给出定义(并且只能定义一次)