热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:C++11常用语法壹

篇首语:本文由编程笔记#小编为大家整理,主要介绍了C++11常用语法-壹相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了C++11常用语法-壹相关的知识,希望对你有一定的参考价值。








文章目录


  • 1.列表初始化
    • 1.1内置类型列表初始化
    • 1.2自定义类型列表初始化

  • 2.变量类型的推导
    • 2.1 编译时类型推导auto
    • 2.2运行时类型推导 decltype

  • 3.final、override
  • 4.新增容器
  • 5.默认成员函数控制
  • 6.右值引用
    • 6.1普通引用和右值引用
    • 6.2 移动语义
    • 6.3为什么提出右值引用
    • 6.4总结
    • 6.5右值引用引用左值
      • 6.5.1使用方法介绍
      • 6.5.2使用场景分析





1.列表初始化

C++ 98之中,只能对数组进行列表初始化,在C++ 11 之中添加了新语法,可以对内置类型列表初始化、自定义类型的列表初始化


1.1内置类型列表初始化

在这里插入图片描述


1.2自定义类型列表初始化

1.支持单个对象的列表初始化
在这里插入图片描述

2.多个对象的列表初始化(不支持序列式类型)

多个对象想要初始化,需要给该类添加一个带有initializer_list类型参数的构造函数即可。
initializer_list是系统自定义的类模板,该模板中主要有三个方法:begin(),end()迭代器,以及获取区间中元素个数的方法size()

在这里插入图片描述


2.变量类型的推导

2.1 编译时类型推导auto

作用:简化类型写法
缺点:可读性变差

auto是编译时,根据初始化表达式类型进行推导的
因此,auto对运行时的类型推导是无能为力的


2.2运行时类型推导 decltype

C++ 98支持的RTTI(运行时类型识别)

typeid只能查看类型不能用其结果定义类型
dynamic_cast只能应用于含有虚函数的继承体系中

运行时类型识别的缺陷是降低程序运行的效率

decltype是根据表达式的实际类型推演出定义变量时所用的类型:

1.推演表达式类型作为变量的定义类型
2.推演函数返回值的类型
在这里插入图片描述


3.final、override

final:修饰虚函数,表示该虚函数不能再被继承

override:检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错
详情


4.新增容器

静态数组 array:没什么用,在栈上开辟的静态数组,灵活性不够
forward_list:单链表
unordered系列


5.默认成员函数控制

C++中的空类,会默认生成一些成员函数,但是这些函数如果程序员自己编写了,就不会默认生成。然而有时候又需要默认生成,这就容易造成混乱,因此C++11,提供两个关键字,让程序员自己决定是否需要编译器生成

default
在默认函数定义或者声明时加上=default,可以显示的指示编译器生成该函数的默认版本,用=default修饰的函数称为显示缺省函数

delete
在C++98之中,将函数设置成private并且不给定义,其它人就无法调用
在C++11之中,主需要在函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,常用于防止拷贝
在这里插入图片描述


6.右值引用

左值:使用空间
右值:使用内容

C++ 11 中对右值进行了严格的区分(除了右值就是左值):
纯右值: 比如 a+b, 100

将亡值: 比如表达式的中间结果,函数按照值的方式进行返回


6.1普通引用和右值引用

C++98之中:普通引用只能引用左值,不能引用右值,const引用既可以引用左值,又可以引用右值

C++11中的右值引用:只能引用右值,一般情况下不能直接引用左值


6.2 移动语义

C++ 11 提出了移动语义的概念:将一个对象中资源转移到另一个对象的方式,可以有效的缓解拷贝构造对象时,资源浪费的情况


6.3为什么提出右值引用

右值引用表示指向的实体为右值,实体的资源可以直接被拿走,提高拷贝的效率,本质上为浅拷贝

#include "test.h"
class String
{
public:
String(const char *str="")
:_str(new char[strlen(str) + 1])
{
strcpy(_str, str);
cout << "String(const char *str&#61;"")" << endl;
}
//正常构造
String(const String &str)
:_str(new char[strlen(str._str)&#43;1])
{
strcpy(_str, str._str);
cout << "String(const String &str)" << endl;
}
//移动构造
String(String &&str)
:_str(str._str)
{
str._str &#61; nullptr;
cout << "String(const String &&str)" << endl;
}
//移动赋值
String &operator&#61;(String &&str)
{
cout << " String &operator&#61;(String &&str)" << endl;
if (_str !&#61; str._str)
{
_str &#61; str._str;
str._str &#61; nullptr;
}
return *this;
}
//正常赋值
String& operator&#61;(const String &str)
{
if (_str !&#61; str._str)
{
cout << "String &operator&#61;(String &str)" << endl;
_str &#61; new char[strlen(str._str) &#43; 1];
strcpy(_str, str._str);
}
return *this;
}
~String()
{
if (_str)
{
delete[]_str;
cout << "~String()" << endl;
}
}
private:
char *_str;
};
String Getstring()
{
String ret("123");
return ret;
}
void test()
{
cout << "使用右值&#xff0c;移动构造" << endl;
String str &#61; Getstring();
cout << endl;

cout << "使用左值&#xff0c;正常构造" << endl;
String str2(str);
cout << endl;
cout << "使用左值&#xff0c;正常赋值" << endl;
str &#61; str2;
cout << endl;
cout << "使用右值&#xff0c;移动赋值" << endl;
str &#61; "123";
cout << endl;
}
int main()
{
test();
system("pause");
return 0;
}

在这里插入图片描述

在这里插入图片描述


6.4总结

在这里插入图片描述


6.5右值引用引用左值


6.5.1使用方法介绍

在某些场景之下&#xff0c;需要用右值去引用去引用左值实现移动语义。当需要一个右值引用引用一个左值时&#xff0c;可以通过move函数将左值转化为右值。C&#43;&#43;11中&#xff0c;std::move()函数位于头文件之中&#xff0c;它并不搬移任何东西&#xff0c;唯一的功能就是将一个左值强制转化为右值引用&#xff0c;然后实现移动语义
在这里插入图片描述


6.5.2使用场景分析

自定义类型String和上述一致

场景1&#xff1a;

class Person
{
public:
Person(const String &name)
:_name(name)//调用String的拷贝构造函数
{}
Person(const Person& pl)
:_name(pl._name)
{
cout << "Person(const Person& pl)" << endl;
}
private:
String _name;
};

在这里插入图片描述

场景2:对场景1的拷贝构造进行优化&#xff0c;使用右值引用:

class Person
{
public:
Person(const String &name)
:_name(name)//调用String的拷贝构造函数
{}
Person(const Person& pl)
:_name(pl._name)
{
cout << "Person(const Person& pl)" << endl;
}
Person(const Person&& pl)
:_name(pl._name)//pl中的string是左值&#xff0c;所以还是调用的深拷贝
{
cout << "Person(const Person&& pl)" << endl;
}
private:
String _name;
};

在这里插入图片描述

场景3:使用进一步的优化

class Person
{
public:
Person(const String &name)
:_name(name)//调用String的拷贝构造函数
{}
Person(const Person& pl)
:_name(pl._name)
{
cout << "Person(const Person& pl)" << endl;
}
Person(Person&& pl)
:_name(move(pl._name))//pl既然是一个将亡值&#xff0c;那么它的资源也是一个将亡值
{
cout << "Person(Person&& pl)" << endl;
}
private:
String _name;
};

在这里插入图片描述

移动语义错误用例:
在这里插入图片描述

移动语义正确使用场景&#xff1a;需要保证属性被修改的左值后面不会再用到






推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
author-avatar
瑩影貓貓05
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有