C++的vector使用優化

我們在上一章說了如何使用這個vector動態數組,這章我們說說如何更好的使用它以及它是如何工作的。當你創建一個vector,然后使用push_back添加元素,當當前的vector的內存不夠時,會從內存中的舊位置復制到內存中的新位置,然后刪除刪除舊位置的內存,也就是說當我push_back,vector容量不夠添加元素就會調整大小,重新分配,這也就是將代碼拖慢的原因之一。是事實,我們需要不斷的重新分配,這是一個非常緩慢的操作,應該避免。我們如何避免復制對象,如果我們處理的是vector,特別是基于vector的對象,我們沒有存儲vector指針,我們存儲的是vector對象,那占的內存就更大了,所以我們要優化復制。

#include <iostream>
#include <string>
#include <vector>struct Vertex
{float x, y, z;Vertex(float x, float y, float z): x(x), y(y), z(z){}//拷貝構造Vertex(const Vertex& vertex): x(vertex.x), y(vertex.y), z(vertex.z){std::cout << "Copied!" << std::endl;}
};int main()
{std::vector<Vertex> vertices;//打印6次//vertices.push_back(Vertex(1, 2, 3));//vertices.push_back(Vertex(4, 8, 9));//vertices.push_back(Vertex(7, 5, 6));//打印3次vertices.reserve(3);vertices.push_back(Vertex(1, 2, 3));vertices.push_back(Vertex(4, 8, 9));vertices.push_back(Vertex(7, 5, 6));std::cin.get();//打印0次vertices.emplace_back(1, 2, 3);vertices.emplace_back(14, 4, 6);vertices.emplace_back(7, 8, 9);}

在上面這段代碼中,我們復制了6次(調用了6次拷貝構造函數),這個是為什么呢?當我們在push_back的時候,我們實際是在,主函數的當前幀中構造它,所以我們在main的棧上創建它,然后我們需要做的是,把它放到這個vector中,所以我們是從main函數中(把這個創建的vertex)放到實際的vector中。

在 C++ 中,std::vector?是一個動態數組,它可以調整其大小以容納不同數量的元素。當你調用?reserve?方法時,你告訴?vector?它應該預先分配足夠的內存來存儲指定數量的元素,但并不會真正添加這些元素。這樣做的好處是,當你稍后添加元素到?vector?時,它可能不需要重新分配內存(如果添加的元素數量沒有超過預留的數量),這可以提高效率,因為內存分配通常是一個昂貴的操作。

在我們的代碼中,由于預留了 3 個元素的空間,因此當你添加前三個元素時,不需要重新分配內存,所以不會調用拷貝構造函數(除了可能的隱式移動構造函數或復制省略,但這些在這個例子中都不適用,因為直接傳遞了臨時對象)。但是,如果你沒有調用?reserve,并且?vector?的初始容量小于你要添加的元素數量,那么在添加元素時可能需要重新分配內存。在重新分配內存時,舊的元素會被拷貝(或移動)到新的內存位置,這就會調用拷貝構造函數(或移動構造函數)。

當你使用?vertices.emplace_back(1, 2, 3);(以及類似的?emplace_back?調用)時,你實際上是在告訴?std::vector?直接在其內部存儲中構造?Vertex?對象,而不是先創建一個臨時對象然后再將其拷貝或移動到?vector?中。這是?emplace_back?相較于?push_back?的主要優勢之一,因為它避免了不必要的拷貝或移動操作,從而提高了效率。

由于?emplace_back?直接在?vector?的內存中構造對象,它不會調用?Vertex?的拷貝構造函數。相反,它會調用?Vertex?的構造函數,直接傳遞參數給構造函數來構造對象。這就是為什么你在使用?emplace_back?后沒有看到 "Copied!" 的輸出。而是三次Constructed!

#include <iostream>
#include <string>
#include <vector>struct Vertex
{float x, y, z;Vertex(float x, float y, float z): x(x), y(y), z(z){std::cout << "Constructed!" << std::endl;}//拷貝構造Vertex(const Vertex& vertex): x(vertex.x), y(vertex.y), z(vertex.z){std::cout << "Copied!" << std::endl;}
};int main()
{std::vector<Vertex> vertices;vertices.reserve(3);vertices.emplace_back(1, 2, 3);vertices.emplace_back(14, 4, 6);vertices.emplace_back(7, 8, 9);std::cin.get();
}

運行上述代碼,你會看到 "Constructed!" 被打印了3次,而不是 "Copied!",因為?emplace_back?直接在?vector?的內存中構造了?Vertex?對象。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/21831.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/21831.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/21831.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring 之 Lifecycle 及 SmartLifecycle

最近在看Eureka源碼&#xff0c;本想快速解決這場沒有硝煙的戰役&#xff0c;不曾想阻塞性問題一個接一個。為正確理解這個框架&#xff0c;我不得不耐著性子&#xff0c;慢慢梳理這些讓人困惑的點。譬如本章要梳理的Lifecycle和SmartLifecycle。它們均為接口&#xff0c;其中后…

mysql的鎖(全局鎖)

文章目錄 mysql按照鎖的粒度分類全局鎖概念&#xff1a;全局鎖使用場景&#xff1a;全局鎖備份案例&#xff1a; mysql按照鎖的粒度分類 全局鎖 概念&#xff1a; 全局鎖就是對整個數據庫實例加鎖。MySQL 提供了一個加全局讀鎖的方法&#xff0c;命令是: Flush tables with…

java —— 文件的創建、刪除、查詢和重命名

文件的相關操作通過 File 類并引入路徑來實現&#xff0c;這里對文件的操作只是對文件本身的增、刪、查等&#xff0c;不包括對文件內容的修改。 一、創建文件/文件夾 public static void main(String[] args) {//創建文件File file1new File("D:\\android\\test\\a.jpg…

vue封裝url驗證方法

vue封裝url驗證方法 在 Vue 中&#xff0c;你可以封裝一個 URL 驗證的方法來驗證給定的 URL 是否有效。以下是一個示例代碼&#xff1a; export const validateUrl (url) > {const regex /^(https?:\/\/)?([\da-z.-])\.([a-z.]{2,6})([/\w .-]*)*/;return regex.test(…

排序算法——歸并排序以及非遞歸實現

一、歸并排序思想 歸并排序&#xff08;MERGE-SORT&#xff09;是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法&#xff08;Divide andConquer&#xff09;的一個非常典型的應用。將已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每個子序列…

OkHttp,一個賊牛的Java工具包

在當今的網絡應用開發中,Java 作為一種成熟的編程語言,廣泛應用于服務器端和客戶端的開發。網絡請求作為應用開發中不可或缺的一部分,選擇一個高效、穩定的網絡庫尤為重要。OkHttp 就是這樣一款優秀的網絡庫,它為Java提供了簡單易用、功能強大的網絡請求能力。本文將向讀者…

關于編譯的一些思路和猜想

一、編譯原理的難度 編譯原理特別復雜&#xff0c;研究的是高級語言如何翻譯成匯編語言的過程。 二、編譯過程中一些思路 (一)語義識別的作用 語義識別指的是把一些無關字符忽略&#xff0c;把一些變量名保存在一起&#xff0c;把用空格隔開的關鍵字單獨放一起。 例如&#…

重新ysyx

一、克隆倉庫 1.創建ssh key ssh-keygen -t rsa cd ~/.ssh ls 查看里面是否有id_rsa id_rsa.pub ssh-keygen -t rsa -C "xiantong15834753336outlook.com" cat id_rsa.pub***********查看里面的內容&#xff0c;復制到下圖中綠色的按鈕 git init ssh -T g…

spark3.0.1版本查詢Hbase數據庫例子

需求背景 現有需求&#xff0c;需要采用spark查詢hbase數據庫的數據同步到中間分析庫&#xff0c;記錄spark集成hbase的簡單例子代碼 import org.apache.hadoop.hbase.HBaseConfiguration import org.apache.hadoop.hbase.client.{ConnectionFactory, Scan} import org.apach…

Marin說PCB之Max parallel知多少?

今天是個陽光明媚&#xff0c;萬里烏云的好日子。小編我一如既往地到家打開電腦準備看騰訊視頻的五十公里桃花塢的第四季&#xff0c;在看到汪蘇瀧汪臺說650電臺要解散的時候小編我差點也哭了。650電臺之于桃花塢就像樂隊的鼓手一樣&#xff0c;都是一個團隊的靈感啊&#xff0…

CSS中的長度單位詳解

在CSS中&#xff0c;長度單位是定義元素尺寸、間距、邊距等的重要工具。不同的長度單位具有不同的特性和使用場景。 絕對長度單位 絕對長度單位在所有設備和瀏覽器中表示相同的長度。這些單位包括&#xff1a; 1.像素&#xff08;px&#xff09; 像素是最常用的長度單位。一…

C語言分支和循環(2)

我的相關博客&#xff1a; C語言的分支與循環&#xff08;1&#xff09; 1.switch語句 除了 if 語句外&#xff0c;C語?還提供了 switch 語句來實現分?結構。 switch 語句是?種特殊形式的 的 if...else 結構&#xff0c;?于判斷條件有多個結果的情況。它把多重 else if…

非質量成本總結

非質量成本 非質量成本 定義 舉例 固定成本 不隨生產量或工作量變動而變動的成本 辦公室租賃費 可變成本 隨著生產量或工作變動而變動的成本 材料費 直接成本 可以直接計入某項目的成本 工人工資 間接成本 不能直接計入某項目而需要再幾個項目之間或在項目與職能部…

Linux基本指令3

Linux基本指令3 目錄 Linux基本指令3 一、Linux文件系統管理 二、Linux進程與服務管理

億發:制造型企業信息化規劃——從破冰到全面落地

在制造型企業中&#xff0c;信息化規劃的落地是一個復雜而關鍵的過程。盡管規劃和藍圖可能已經制定完畢&#xff0c;但如何成功地實施信息化才是關鍵所在。本文將詳細介紹制造型企業信息化規劃的落地過程&#xff0c;通過三個周期逐步推進&#xff0c;最終實現信息化與自動化的…

深度學習知識與心得

目錄 深度學習簡介 傳統機器學習 深度學習發展 感知機 前饋神經網絡 前饋神經網絡&#xff08;BP網絡&#xff09; 深度學習框架講解 深度學習框架 TensorFlow 一個簡單的線性函數擬合過程 卷積神經網絡CNN&#xff08;計算機視覺&#xff09; 自然語言處理NLP Wo…

OpenAI助手API接入-問答對自動生成

支持GPT-3.5-Turbo, GPT-4o, GPT-4-Turbo import json import openai from pathlib import Path import os client openai.OpenAI(base_urlbase_url, api_keyapi_key) file client.files.create( fileopen("H3.pdf", "rb"), purposeassistants ) …

HTTP 的三次握手

????? HTTP 的三次握手是指在建立 TCP 連接時&#xff0c;客戶端和服務器之間進行的三步握手過程。這個過程確保了雙方都能夠互相通信&#xff0c;并且同步了彼此的序列號和確認號。 概念&#xff1a; 第一次握手&#xff1a;客戶端發送一個 SYN&#xff08;同步…

2.1數據的表示和運算--進位制

2.數據的表示和運算 2.1進位制 &#x1f53a;問題&#xff1a;計算機采用二進制有什么優點&#xff1f; 答&#xff1a; 1.制造兩個穩態的物理器件較容易。 2.二進制的運算規則簡單。 3.便于用邏輯門電路實現運算。 4.二進制的0和1正好對應邏輯值真和假。 &#x1f53a;…

成功解決“ModuleNotFoundError: No Module Named ‘utils’”錯誤的全面指南

成功解決“ModuleNotFoundError: No Module Named ‘utils’”錯誤的全面指南 在Python編程中&#xff0c;遇到ModuleNotFoundError: No Module Named utils這樣的錯誤通常意味著Python解釋器無法找到名為utils的模塊。這可能是由于多種原因造成的&#xff0c;比如模塊確實不存…