STL——vector以及emplace_back分析

2023-11-17

在这里插入图片描述
1、这里需要注意凡是连续空间的容器都提供operator[],[]是为了数组操作
2、back()应该是*(end()-1)!!!
3、vector的大小为12;

在这里插入图片描述
在这里插入图片描述
vector的迭代器为指针
在这里插入图片描述

1. emplace_back

1. 相比push_back,如果传入临时对象T(1),则没有区别,都会调用emplace_back,并通过move,如果传入1,那么push_back则需要两步,先构造函数,再move,而emplace_back则只需要最后调用构造函数
2. 由于其构造函数的特殊性,支持传入多个参数,通过默认构造函数生成右值,并完成构造(push_back也可以)
3. 与push_back的区别在于,构造应在容器中完成,而非在容器外完成,所以不需要move或者拷贝构造!


#include <vector>
#include <iostream>
using namespace std;
class T
{
    public:
    T(int i){cout<<"111111111"<<endl;};
    T(const T& t){cout<<"222222222"<<endl;}
    T( T&& t){cout<<"333333333"<<endl;}
};


int main()
{
    vector<T> va;
    va.reserve(100);
    va.push_back(1);
    cout<<"~~~~~~~~~~"<<endl;
    va.emplace_back(1);
}
PS C:\C++\test> cd "c:\C++\test\" ; if ($?) { g++ a.cpp -o a } ; if ($?) { .\a }
111111111
333333333
~~~~~~~~~~
111111111

可见其只是少了一个构造而已

查了下源码,跳过中间一堆的forward与move,最后区别就在这个placement NEW

  1. push_back由于在传入前已经隐形类型转换,构造好了。所以这里是走的拷贝构造或者move
  2. emplace_back如果传入已经构造好的,T(i),那么与push_back类似
  3. emplace_back如果传入构造T所需的入参i等,那么这里只是走构造函数而已
    在这里插入图片描述

在这里插入图片描述

class Test
{
    public:
    Test(Test&& t)
    {
        cout<<"apple"<<endl;
    }
    Test(const Test& t) = default;
    Test(int i){cout<<"banana"<<endl;};
    // Test(const Test&) = delete;

};
template<class T>
unique_ptr<T> fun(T a)
{
    auto p = unique_ptr<T>(new T(a));
    return p;
}

Test funT(int t)
{
    Test tt = Test(t);
    return tt;
}
int main()
{
    auto a =  fun(1);
    Test s = funT(1);
    vector<Test> t;
    t.reserve(10);
    t.emplace_back(2);   //构造二次
    t.push_back(3);     // 构造一次,move一次
    return 0;
banana
banana
banana
apple
class C3{
public:
    C3(){}
    C3(int ii,string ss):i(ii),s(ss){cout << " constructor " << endl;}
    C3(const C3& c):i(c.i+100),s(c.s + "hhhhhhhhhhh"){cout << " copy constructor " << endl;}
int i;
    string s;
};

main 函数:
        vector <C3> vC;
        vC.push_back(C3(1,"ss"));
        cout << vC[0].i << endl;
        cout << endl;
        vC.emplace_back(3,"kk");
        cout << vC[1].i << " " << vC[0].i << endl;


输出:

 constructor 
 copy constructor 
101

 constructor 
 copy constructor 
3 201

2. begin函数

函数原型:

iterator begin();

const_iterator begin();

功能:

返回一个当前vector容器中起始元素的迭代器。

3. end函数

函数原型:

iterator end();

const_iterator end();

功能:

返回一个当前vector容器中末尾元素的迭代器。

4.front函数

函数原型:

reference front();

const_reference front();

功能:

返回当前vector容器中起始元素的引用。

5.back函数

函数原型:

reference back();

const_reference back();

功能:

返回当前vector容器中末尾元素的引用。

6.reserve和resize

  1. vector 的reserve增加了vector的capacity,但是它的size没有改变!
  2. resize改变了vector的capacity同时也增加了它的size!
    原因如下:
    reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。加入新的元素时,要调用push_back()/insert()函数。
    resize是改变容器的大小,且在创建对象,因此,调用这个函数之后,就可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符,或者用迭代器来引用元素对象。此时再调用push_back()函数,是加在这个新的空间后面的。
vector<int> myVec;
myVec.reserve( 100 );     // 新元素还没有构造, 
                                       // 此时不能用[]访问元素
for (int i = 0; i < 100; i++ )
{ 
     myVec.push_back( i ); //新元素这时才构造
}
myVec.resize( 102 );      // 用元素的默认构造函数构造了两个新的元素
myVec[100] = 1;           //直接操作新元素
myVec[101] = 2;  

不管是调用resize还是reserve,二者对容器原有的元素都没有影响。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STL——vector以及emplace_back分析 的相关文章

随机推荐

  • JS考点

    JavaScript 1 原始值和引用值类型及区别 原始值即存在栈中的数据 包含symbol number string null undefined boolean类型 引用值即存在堆中的对象 对象地址 指针 存在栈中 指向堆中存储的数据
  • 2021-07-25

    神经网络 M P神经元 感知机 感知机 神经网络 M P神经元 1 M P神经元 模拟生物行为的数学模型 接手n个输入 来自其他的神经元 并给各个输入赋予权重计算加权和 再跟自己特有的阀值 比较 通常用减法 最后经过激活函数 模拟 抑制 和
  • Stable Diffusion Base Model from safetensors transfer to diffusers

    Steps File Setup Clone the ControlNet model repo from HF into a folder like hf controlnet model git clone https huggingf
  • Qt 中父子关系使用总结

    背景 Qt 中到父子关系和类的继承无关 仅表示对象间到从属关系 继承自 QObject 的对象在构造时需要指定父对象指针 include
  • 计算机基础知识+Java语言基础 +JAVA学习笔记-DAY01

    计算机基础知识 01 01 计算机概述 了解 A 什么是计算机 计算机在生活中的应用举例 计算机 Computer 全称 电子计算机 俗称电脑 是一种能够按照程序运行 自动 高速处理海量数据的现代化智能电子设备 由硬件和软件所组成 没有安装
  • Cent OS6.5 安装nodeJS(分分钟搞定)

    第一步 下载 cd opt wget https nodejs org dist v7 5 0 node v7 5 0 linux x64 tar xz 第二步 解压缩文件包 xz d node v7 5 0 linux x64 tar x
  • hive原理与源码分析-hive源码架构与理论(一)

    什么是Hive 数据仓库 存储 查询 分析大规模数据 SQL语言 简单易用的类SQL查询语言 编程模型 允许开发者自定义UDF Transform Mapper Reducer 来更简单地完成复杂MapReduce无法完成的工作 数据格式
  • 运放增加输出电流

    功率输出模块 采用三极管9012 9013来进行双向扩流以提高其带载能力 可以完全满足发挥部分所要求的稳幅输出能力 当负载变化时 其输出电压幅度变化小于3 如图所示 集成运放的扩流和扩压 一 集成运放的扩流 在集成运放的输出端再加一级互补对
  • k8s-client(java)从6.0.1升级到11.0.0出现patch问题may not be specified for non-apply patch/cannot unmarshal...

    背景 kubernetes client java升级 复杂的patch出现各种问题 并且没有找到解决方案 经过研究 测试 找到了解决方案 希望能帮助到使用kubernetes client java客户端的同学 patch方法调用出现异常
  • IEEE 1471(ISO/IEC/IEEE 42010)架构描述方法

    ISO IEC IEEE 42010 架构描述方法 关于 背景 架构描述 利益相关者和关注点 架构视图和架构观点 架构模型 架构关系 架构原理 关于 本文对软件体系架构的描述方法的研究基于 ISO IEC IEEE 42010 ISO IE
  • unity ethan_响应式网页设计的挑战,Ethan Marcotte

    unity ethan In this episode of the Versioning Show David and Tim are joined by Ethan Marcotte a well known designer who
  • c语言设计(TVI)地铁自动售票机---@颜麓

    设计TVI 地铁自动售票机 机软件 输入站数 计算费用 计费规则 6站2元 7 10站3元 11站以上为4元 输入钱数 计算找零 找零时优先找回面额大的钞票 找零方式为各种面额张数 可识别面额 100 50 20 10 5 1 includ
  • Sentinel整合Ribbon/OpenFeign,Sentinel自定义限流熔断

    Sentinel服务熔断环境搭建 服务熔断 应对微服务雪崩效应的一种链路保护机制 类似保险丝 需要完成Sentinel整合Ribbon openFeign 所以我们先要搭建环境 那么先从整合Ribbon开始 环境搭建 为了演示操作 所以在这
  • DBeaver改成英语

    DBeaver改成英语 安装目录中有个dbeaver ini文件 追加 Duser language en可以改回英文 有些数据库术语翻译后反而不太容易理解
  • java获取唯一时间戳Id.多线程保证唯一性

    工程里有获取唯一时间戳作为id的需求 想了想用乐观锁cas实现 自旋 cas原子性操作获得了绝对唯一的时间戳 系统时间 纳秒版本 单机有效 不能分布式调用 public class AtomicTimeStamp private Atomi
  • Anaconda的安装与环境配置

    这里简单的记录一下Anaconda的安装过程 没有干货 只是记录 但也看了就会 下载安装包 这里有两个下载地址 分别是官网和清华镜像源 推荐清华镜像 下的快 官网下半天还可能失败 无论是哪个下载地址 找到对应你系统的安装程序下载即可 官网
  • Ubuntu下安装JDK图文教程详解

    操作系统 Ubuntu 11 10 我们选择的是jdk1 6 0 30版本 安装文件名为jdk 6u30 linux i586 bin 1 复制jdk到安装目录 1 假设jdk安装文件在桌面 我们指定的安装目录是 usr local jav
  • 可以编辑的table antd

    版本一 效果图 有保存按钮 antd3 代码 import React Component from react import Form Input Button Table Divider Popconfirm Tooltip from
  • 19_复制目录下所有文件夹和目录CopyFile()

    复制目录下所有文件夹和目录CopyFile 想一下 若要复制文件夹 可以在目录位置新建一个文件夹 然后将源文件夹中里面的文件进行遍历 一个一个的复制到目标文件夹中即可 void EnumCopyFile 输入参数 TCHAR szSrcRo
  • STL——vector以及emplace_back分析

    1 这里需要注意凡是连续空间的容器都提供operator 是为了数组操作 2 back 应该是 end 1 3 vector的大小为12 vector的迭代器为指针 1 emplace back 1 相比push back 如果传入临时对象