首页 > 编程语言 >C++必知必会 C++11实用特性

C++必知必会 C++11实用特性

时间:2024-03-23 21:02:59浏览次数:28  
标签:11 const 函数 右值 必知 C++ int 对象

文章目录


前言

C++11开始添加了很多好用的新特性,个人认为想要真正掌握这些特性还是需要多读代码,多应用这些特性,本文只记录了一些个人用过的,并结合自己的使用体验讲了一下使用场景


nullptr和NULL

C++11中NULL表示的是一个int类型的0,用nullptr来表示空指针以避免野指针,悬空指针等问题,nullptr允许隐式转换为其它类型的指针

const和constexpr

1.const
const在C++11之前就有,用处在于变量只读以及修饰常量,但要注意两者是不一样的

  • 变量只读:比如函数中我们不希望传入的参数被修改void func (const int num)
  • 修饰常量:有时提前定义一个常量,并用于描述数组大小const int a = 20; int arr[a];

2.constptr
首先讲明constexpr和const的区别:在修饰常量方面,二者都可用,但是constexpr达不到修饰变量只读的作用,所以在参数传递的时候只能用const来修饰其只读的效果

1.使用意义:constexpr所声明的表达式或函数,必须在编译期间完成运算,这就意味着其作用主要是用于优化程序,个人认为,如果不是厉害的cpper,用好const就够了。
2.使用场景:

声明变量:
constexpr int max_size = 100; // 编译时常量
const int max_size = 100; // 编译时const
const int max_size = N;//运行时const
声明函数(前提是所有参数也都是编译时常量):
constexpr int add(int x, int y) {
    return x + y;
}

constexpr int val = add(5, 3); // 编译时求值

auto和decltype

1.auto用于编译期间类型推导,主要用于stl的遍历,不能用于形参的推导
2.decltype用于表达式类型的推导,其也是在编译阶段实现的,使用 decltype推导出的是表达式类型的引用,decltype通常与尾返回类型推导结合使用,来获取函数的返回类型,而decltype前置时变量会未定义,如:decltype(x+y) add(T x, U y)是不对的,正确的应该是这样

template<typename T, typename U>  
auto add2(T x, U y) -> decltype(x+y){  
return x + y;
}

在C++11之前,函数的返回值类型必须显示的定义在函数前面,在C++11及以后的标准中可以使用尾返回类型推导来让编译器推导函数的返回类型

lambda表达式

lambda表达式定义了一个匿名函数,并且可以捕获一定范围内的变量。其最大的好处就是使用时再定义

[capture](params) opt -> ret {body;};
[] - 不捕捉任何变量 
[&] - 捕获外部作用域中所有变量, 并作为引用在函数体内使用 (按引用捕获) 
[=] - 捕获外部作用域中所有变量, 并作为副本在函数体内使用 (按值捕获) 拷贝的副本在匿名函数体内部是只读的

- opt:函数选项,没有可以不写 

一般来说,我们使用lambda表达式只需要关注捕获列表,函数参数,函数体即可,举个例子,sort函数默认进行从小到大的排序,如果我们希望修改排序规则,那么就要在sort的第三个参数位置传入一个函数来修改规则:

vector<int> nums;
sort(nums.begin(), nums.end(), [&] (int a,int b){
	return a>b;
};)

function和bind

1.function的目地在于封装各种各样的可调用实体,形成一个新的可调用的function对象,另外function对象是对可调用对象的一种类型安全的包装,相比于类型不安全的函数指针更适合作为回调函数。
个人在使用中,主要是用function包装一个仅在本函数中使用的函数,通过function+lambda表达式来实现,举个例子:在进行图论的算法题中经常会用到dfs算法,我们可以直接在main函数中定义dfs函数,并实现调用

int main()
{
	//这里包装的dfs函数可以在
	function<void(int,int)> dfs = [&](int x, int y){
		//函数逻辑
	};
	...
	dfs(3,5);
}

可调用对象主要有以下几种:

  • 重载了函数调用运算符()的类的对象,即为函数对象(仿函数)
  • 函数
  • 函数指针
  • lambda表达式

2.bind
它主要用于将可调用对象(如函数、成员函数、函数对象)与其参数绑定,创建一个新的可调用对象。例如:

void print(int a, int b) {
    std::cout << a << ", " << b << std::endl;
}

class Foo {
public:
    void display(int x) {
        std::cout << x << std::endl;
    }
};

int main() {
    // 绑定全局函数的参数
    auto boundFunc = std::bind(print, 42, std::placeholders::_1);
    boundFunc(24); // 输出: 42, 24

    Foo foo;
    // 绑定成员函数及其对象
    auto boundMemberFunc = std::bind(&Foo::display, &foo, std::placeholders::_1);
    boundMemberFunc(15); // 输出: 15
}

std::placeholders::_1、std::placeholders::_2…这些表示的是参数占位符,通常表示未进行绑定的那些参数

右值引用

1.右值和左值:左值可以取地址,右值不能取地址。
2.右值引用,用&&表示,它主要用于支持移动语义(Move Semantics)和完美转发(Perfect Forwarding),右值引用允许我们安全地引用临时对象
3.右值引用通常用于延长临时对象的生命周期,使得可以直接使用它,而不是把它拷贝给我们自己定义对象,它提高了程序的效率,比如说有时我们会通过一个临时对象来构造我们的对象,如果这个临时对象本身就很大,它创建出来已经耗费了一部分系统资源,然后还要再拷贝给我们自己的对象,拷贝完再销毁这个临时对象,整个过程的开销是很大的。
4.通常用于移动构造函数和移动赋值操作符重载函数

Example(Example&& other){}
Example& operator=(Example&& other){
	return *this;
}

移动语义move

在C++11添加了右值引用,并且不能使用左值初始化右值引用,如果想要使用左值初始化一个右值引用需要借助std::move()函数,使用std::move方法可以将左值转换为右值。使用这个函数并不能移动任何东西,而和移动构造函数一样都具有移动语义,将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存拷贝

智能指针

智能指针对于C++的内存安全来说是一个重大的更新,值得我们单独讲一下,看我的这篇文章智能指针详解

标签:11,const,函数,右值,必知,C++,int,对象
From: https://blog.csdn.net/m0_56049283/article/details/136963312

相关文章

  • 【华为OD机试】真题A卷-连接器问题(C++)
    一、题目描述【华为OD机试】真题A卷-连接器问题(C++)题目描述:有一组区间[a0,b0],[a1,b1],…(a,b表示起点,终点),区间有可能重叠、相邻,重叠或相邻则可以合并为更大的区间;给定一组连接器[x1,x2,x3,…](x表示连接器的最大可连接长度,即x>=gap),可用于将分离的区间连接起来,但两个分离区间之间只......
  • 突破编程_C++_C++11新特性(lambda表达式的基础知识)
    1Lambda表达式简介1.1Lambda表达式的定义与概念Lambda表达式是C++11引入的一种函数对象的匿名表示方法,它的定义与概念基于数学中的λ演算。Lambda表达式为程序员提供了一种更加简洁、灵活的方式来定义轻量级的、临时的、内联的函数对象,通常用于函数式编程的场景......
  • CF1711B Party 题解
    CF1711BParty原题题意给定$n$个点带点权的无向图,点权$a_i$保证无重边自环,点权非负),要求删去一些点和它相连的边,使得剩下这个图的边数为偶数且删去点的点权之和最小。问删去点的点权之和最小是多少?分类讨论我们分类讨论一下。$m$为偶数,则不需要删边或点,直接输出$0$即......
  • ZCMU_1117
    /相当于看墙,投影之类的东西让我数多少个建筑物/解释感觉还不到位,以后再看看先强调这不是我原创的,只是加了注释。找到原作者后会加链接。以及改变布局#include<cstdlib>#include<cassert>#include<stack>usingnamespacestd;intmain(void){inti,n,h,coun......
  • 跳马【华为OD机试JAVA&Python&C++&JS题解】
    一.题目马是象棋(包括中国象棋和国际象棋)中的棋子,走法是每步直一格再斜一格,即先横着或直着走一格,然后再斜着走一个对角线,可进可退,可越过河界,俗称“马走‘日’字。给顶m行n列的棋盘(网格图),棋盘上只有有棋子象棋中的棋子“马”,并且每个棋子有等级之分,等级为k的马可以跳1~k......
  • C++ [NOIP2008 普及组] ISBN 号码
    文章目录一、题目描述[NOIP2008普及组]ISBN号码题目描述输入格式输出格式样例#1样例输入#1样例输出#1样例#2样例输入#2样例输出#2提示二、参考代码一、题目描述[NOIP2008普及组]ISBN号码题目描述每一本正式出版的图书都有一个ISBN号码与之对应,IS......
  • C++ 三角函数
    文章目录一、题目描述三角函数题目描述输入格式输出格式样例#1样例输入#1样例输出#1提示二、参考代码一、题目描述三角函数题目描述输入一组勾股数a,b......
  • C++ 最长连号
    文章目录一、题目描述最长连号题目描述输入格式输出格式样例#1样例输入#1样例输出#1提示数据规模与约定二、参考代码一、题目描述最长连号题目描述输入长度为nn......
  • 字符串翻转(C++)
    示例:        翻转前:tobeornottobe        翻转后:otebrotonoteb基本思路:        利用strtok字符串切割函数拿到每一部分,存储到一个字符串数组中,再将每一个字符串数组倒置。最后顺序输出。程序代码:#include<iostrem>#include<string>#......
  • 2024华为OD统一考试(C卷)最新题库(Java & Python & C++)
    关于华为OD​华为的员工补充途径有三种,分别是校招、OD转正和社招。校招是华为唯一的正式员工入职途径,但是从近几届开始竞争非常激烈,尤其是在CV、AI、NLP等赛道上,所以对于C9等专业的学生来说,可以考虑转向一些冷门方向。​OD转正是指在华为工作满一年之后,可以根据部门OD......