牛客网链接
● 请问C++11有哪些新特性? 参考
1.初始化列表
参考
在C++98中,标准允许使用花括号{}来对数组元素进行统一的集合(列表)初始化操作
列表初始化的方式对:内置类型(int、float、double、char等)、数组、自定义的类、函数参数列表、STL标准模板库等都是有效的。
CClass::CClass() : x(0), y(1){
}
为什么要有列表初始化
(1)设想你有一个类成员C,而且只有一个带一个参数的构造函数。
如果C是另一个类的成员,你怎样初始化它呢?答案是你必须使用成员初始化列表。
(2)如果在构造函数内部赋值:
编译器总是确保所有成员在构造函数体执行之前被初始化,在到达赋值语句前完成就调用过相应的函数了
也就是需要调用两次函数,浪费资源
注:初始化顺序——按照声明的顺序初始化的,而不是按照出现在初始化列表中的顺序。
2.auto关键字 参考2
auto可以在声明变量的时候根据变量初始值的类型自动为此变量选择匹配的类型。
auto 变量必须在定义时初始化。
3.for循环:for(auto c:nums),对容器也适用
4.nullptr关键字 参考3
C++11新标准中又引入了nullptr来声明一个“空指针”。
原因:NULL在C++中的定义,NULL在C++中被宏定义为整数0:在遇到重载时可能会出现问题。
nullptr能够转换成任何指针,而且它不能转换成int。
void Func(char *);
void Func(int);
int main()
{
Func(NULL);
}
5. =default和=delete
C++11允许我们使用=default来要求编译器生成一个默认构造函数,
也允许我们使用=delete来告诉编译器不要为我们生成某个默认函数
B() = default; //显示声明使用默认构造函数
B(const B&) = delete; //禁止使用类对象之间的拷贝
6. 智能指针
auto_ptr不适用了,weak_ptr, shared_ptr, unique_ptr
7.
(1)unordered_map ,unordered_set
无序容器中的元素是不进行排序的,内部通过 Hash 表实现
不关心容器内部元素顺序时,能够获得显著的性能提升。
(2)array
array除了有传统数组支持随机访问、效率高、存储大小固定等特点外
支持迭代器访问、获取容量、获得原始指针等高级功能。而且它还不会退化成指针T *给开发人员造成困惑。
(3)tuple元组容器
而tuple与pair不同的是它可以有任意数量的成员。但是每个确定的tuple类型的成员数目是固定的。
8. 右值引用是用来支持转移语义的。转移语义可以将资源 ( 堆,系统对象等 ) 从一个对象转移到另一个对象,这样能够减少不必要的临时对象的创建、拷贝以及销毁,能够大幅度提高 C++ 应用程序的性能。消除了临时对象的维护 ( 创建和销毁 ) 对性能的影响。参考
MyString a;
a = MyString("Hello"); //仍然调用了拷贝构造和拷贝赋值
我们在设计和实现类时,对于需要动态申请大量资源的类,应该设计右值引用的拷贝构造函数和赋值函数,以提高应用程序的效率。
9.智能指针
智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。C++ 11中最常用的智能指针类型为shared_ptr,它采用引用计数的方法,记录当前内存资源被多少个智能指针引用。该引用计数的内存在堆上分配。当新增一个时引用计数加1,当过期时引用计数减一。只有引用计数为0时,智能指针才会自动释放引用的内存资源。
● 请你回答一下智能指针有没有内存泄露的情况
当两个对象相互使用一个shared_ptr成员变量指向对方,会造成循环引用,使引用计数失效,从而导致内存泄漏
● 请你来说一下智能指针的内存泄漏如何解决
为了解决循环引用导致的内存泄漏,引入了weak_ptr弱指针,weak_ptr的构造和析构不会引起引用计数的增加或减少.