C++面试知识点(二)

目录

1、define、const、typedef 的区别

2、constexpr

constexpr变量:

constexpr函数:

3、内存泄漏及避免

4、new和malloc,delete和free

5、面向对象三大特性

6、 如何写出高质量代码

1、代码规范与可读性

2、内存与资源管理

3、健壮性与异常处理

C++11新特性:

1、auto

auto与decltype 

2、范围基于的 for 循环

3、智能指针

4、 Lambda 表达式

5、移动语义

6、nullptr

7、std::thread 和多线程支持

8、 std::chrono

9、std::initializer_list

10、强类型枚举(enum class)

C++14 新特性

1、二进制字面量

2、std::make_unique

3、返回类型后置

4、泛型 lambda

C++17 新特性

1、std::optional

2、std::variant

3、std::any

4、结构化绑定

5、if constexpr

C++20 新特性

1、概念(Concepts)

2、范围库(Ranges)

3、协程(Coroutines)

4、模块(Modules)


1、define、const、typedef 的区别

define const typedef
发生在编译的预处理阶段,只是简单的字符串替换,使用多少次就多少次替换,没有类型检查不安全;可以用来防止头文件重复引用 用于定义常量生效于编译阶段,有类型,define也可以定义常量不带类型,生效于预处理阶段直接使用不放入内存 有对应的数据类型,在编译、运行阶段是要进行类型判断的;在静态存储区中分配空间,在程序运行过程中内存中只有⼀个拷贝

2、constexpr

constexpr 表示“常量”的语义,只能定义编译期常量,你将⼀个成员函数标记为constexpr,则顺带也将它标记为了const。如果你将⼀个变量标记为constexpr,则同样它是const的。但相反并不成立,⼀个const的变量或函数,并不是constexpr的。

constexpr变量:

复杂系统中很难分辨⼀个初始值是不是常量表达式,可以将变量声明为constexpr类型,由编译器来验证变量的值是否是⼀个常量表达式。初始化 constexpr int n = 1; constexpr int m = n + 1;

constexpr函数:

constexpr函数是指能用常量表达式的函数,函数的返回类型和所有形参类型都是字面值类型,函数体有且只有⼀条return语句。为了可以在编译过程展开,constexpr函数被隐式转换成了内联函数
constexpr和内联函数可以在程序中多次定义,⼀般定义在头文件。
constexpr 构造函数:构造函数不能是const,但字面值常量类的构造函数可以是constexpr。
constexpr构造函数必须有⼀个空的函数体,即所有成员变量的初始化都放到初始化列表中。对象调用的成员函数必须使用 constexpr 修饰。

3、内存泄漏及避免

释义:内存泄漏(memory leak)是程序未能释放掉不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误失去了对该段内存的控制,而造成了内存的浪费,常见于指针指向改变,未释放动态分配的内存。可以用Valgrind, mtrace进行内存泄漏检查。

常见内存泄漏:1)通过malloc,new等从堆中分配的⼀块内存,完成后须通过调用对应的 free或者 delete释放掉。如果程序的设计的错误导致这部分内存没有被释放,那么此后这块内存将不会被使用,产生Heap Leak。2)主要指程序使用系统分配的资源如 Bitmap,handle ,SOCKET 等没有用相应的函数释放掉,导致系统资源的浪费,严重可导致系统效能降低,系统运行不稳定。3)当基类指针指向子类对象时,如果基类的析构函数不是 virtual,那么子类的析构函数将不会被调用,子类的资源没有正确是释放,因此造成内存泄露;

避免:将内存的分配封装在类中,构造函数分配内存,析构函数释放内存;使用智能指针。

4、new和malloc,delete和free

new malloc
C++的运算符,可以为对象分配内存并调用相应的构造函数 malloc 是C语言库函数,只分配指定大小的内存块,不会调用构造函数
new 返回的是具体类型的指针,而且不需要进行类型转换 malloc 返回的是 void* ,需要进行类型转换,因为它不知道所分配内存的⽤途
new 在内存分配失败时会抛出 std::bad_alloc 异常 malloc 在内存分配失败时返回 NULL
new 可以⽤于动态分配数组,并知道数组大小 malloc 只是分配指定大小的内存块,不了解所分配内存块的具体⽤途
delete free
delete 会调用对象的析构函数,然后释放内存,确保资源正确释放 free 只是简单地释放内存块,不会调用对象的析构函数
delete 释放的内存块的指针值会被设置为 nullptr ,以避免野指针 free 不会修改指针的值,可能导致野指针问题
delete 可以正确释放通过 new[] 分配的数组 free 不了解数组的大小,不适用于释放通过 malloc 分配的数组

一般new[]和delete[]要配对使用,因为new[]会创建一个数组,一个对象数组需要一定的空间大小,一个对象需要N个字节,k个对象需要k*N个空间来构造对象,但是delete[]如何知道数组的长度?new[]在k*N的基础上头部多申请4个字节用于存储数组长度,这样delete时候知道对象数组的大小,才会相应调用k次析构函数释放kN+4大小的内存。

如果是内置类型,可以不匹配使用,因为内置类型在申请时知道是内置类型不需要析构函数,也不需要多4个字节存储数组长度只需要直接操作内存即可。

C++ new操作符在内存分配失败时会抛出std::bad_alloc异常而不是返回nullptr,所以理论上不用判空,因为失败进入异处理,如果使用int* p=new(std::nothrow) int;这是失败会返回nullptr需要判空

5、面向对象三大特性

封装:将数据和代码捆绑在⼀起,避免外界干扰和不确定性访问࿱

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值