IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c++ vector容器emplace_back -> 正文阅读

[C++知识库]c++ vector容器emplace_back

  • 为在容器操作时尽可能的减少构造函数的调用和内存的拷贝,C++11 引入了emplace_back的方法,该方法可以改善往容器内推入对象元素时的效率。相比push_back,可以节省一次拷贝构造函数的调用从而提高插入效率;

  • push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程;

  • push_back()方法要调用构造函数和复制构造函数,这也就代表着要先构造一个临时对象,然后把临时的copy构造函数拷贝或者移动到容器最后面;而emplace_back()在实现时,则是直接在容器的尾部创建这个元素,省去了拷贝或移动元素的过程;

  • emplace_back()在容器尾部添加一个元素,调用构造函数原地构造,不需要触发拷贝构造和移动构造。在实际使用时,优先选用 emplace_back()

  • 在调用push_back时,每次执行push_back操作,相当于底层的数组实现要重新分配大小;这种实现体现到vector上,就是每当push_back一个元素,都要重新分配一个大一个元素的存储,然后将原来的元素拷贝到新的存储,之后在拷贝push_back的元素,最后要析构原有的vector并释放原有的内存。如:v.push_back(s1); vector会申请一个内存空间,并调用拷贝构造函数将s1放到vector中;

  • 如果想提高效率时,也可以让容器变为指针容器,到时候直接推入指针变量即可。这样的话,每次推入的代价就由真个类的的拷贝构造函数转为了指针的拷贝,效率会明显提升。

vector<pair<int, int>> ret;
ret.push_back(1,1)//会报错,因为没有构造一个临时对象
ret.push_back(pair(1,1))//不会报错,因为构成了一个pair对象
ret.emplace_back(1,1)//不会报错,因为直接在容器的尾部创建对象
vector<vector<int>> ans;
        int lastcol = INT_MIN;
        for (const auto& [col, row, value]: nodes) {
            if (col != lastcol) {
                lastcol = col;
                ans.emplace_back();//这里的emplace_back()直接在ans的尾部创建一个类型为vector<int>的空对象,如果省去这一行,后面的ans.back()会是一个空指针而报错。
            }
            ans.back().emplace_back(value);
        }
  • 测试代码

#include<iostream>
using namespace std;
#include<string>
#include<vector>
class student {
public:
	student(string s, int a) {
		cout << "构造函数调用" << endl;
		name = s;
		a = age;
	}
	student(const student& s ) {
		cout << "拷贝构造函数调用" << endl;
	}
private:
	string name;
	int age;
};
int main() {
	vector<student> v;
	student s1("tom", 12);
	v.push_back(s1);   //需先创建studnet类对象,才能进行插入操作;
	v.emplace_back("marry", 18);  //无需先创建一个student类对象,就可以直接插入一个类对象到vector容器
	//v.push_back("bob", 19);  //会报错,必须先创建一个student类对象,才能进行尾插操作
	return 0;
}

测试结果输出:当两个插入一起插入时,会触发未知的拷贝构造操作,就会看到两种函数插入方式都调用了拷贝构造函数;

  • 单独进行 emplace_back() 操作;当多次插入操作导致vector已满时,就要分配一块更大的内存(比原始大小多50%),将原始数据复制过来并释放之前的内存。原始数据的复制就是这些拷贝构造操作。
  • 测试代码
#include<iostream>
using namespace std;
#include<string>
#include<vector>
class student {
public:
	student(string s, int a) {
		cout << "构造函数调用" << endl;
		name = s;
		a = age;
	}
	student(const student& s ) {
		cout << "拷贝构造函数调用" << endl;
	}
	~student() {
		cout << "析构函数" << endl;
	}
private:
	string name;
	int age=0;
};
int main() {
	vector<student> v;
	cout << "初始vector容器大小为:" << v.size() << endl;
	v.emplace_back("marry", 18);  
	v.emplace_back("tom", 8);  //至此vecotr容器满,才需调用拷贝构造函数
	cout << "vector容器大小为:" << v.size() << endl;
	v.emplace_back("xiaoming", 28);  
	cout << "vector容器大小为:" << v.size() << endl;
	v.emplace_back("xiaoming", 8);  
	cout << "vector容器大小为:" << v.size() << endl;
	return 0;
}
  • 测试结果输出;当vector容器填满时,则调用一次拷贝构造函数,并调用析构函数释放原来内存空间;下打印的“拷贝构造函数调用”即vector满时,需要分配更大的内存并复制原始数据而产生的。并且每次分配更大内存时,都比原始大小多50%;
  • vector容器:内存空间只会增长,不会减小;为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都紧挨着前一个元素存储。设想一下,当vector添加一个元素时,为了满足连续存放这个特性,都需要重新分配空间、拷贝元素、撤销旧空间

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-06-08 18:52:05  更:2022-06-08 18:52:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:41:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码