You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何调用push_back时vector的每个元素都会触发拷贝构造函数?

Why does std::vector call copy constructor for all elements on push_back?

Hey there! Let's break down what's happening here clearly:

First: The frequent copy constructor calls are normal for std::vector... but avoidable

When you call push_back on a std::vector, if the vector's current capacity isn't enough to hold the new element, it has to do these steps:

  1. Allocate a new, larger block of contiguous memory (vector requires contiguous storage by design)
  2. Copy all existing elements from the old memory to the new block
  3. Destroy the old elements and free up the old memory

This is exactly why you're seeing the copy constructor fire for all existing elements every time the vector expands. Your loop adds 5 elements, and each expansion triggers this copy step.

But wait—you already implemented a move constructor! Why isn't that being used instead? Because in your code:

vec.push_back(lt);

lt is an lvalue (a named object), so push_back uses its lvalue overload which calls the copy constructor. To trigger the cheaper move constructor (it just transfers pointer ownership instead of copying the entire array), cast lt to an rvalue with std::move:

vec.push_back(std::move(lt));

This tells the compiler to use move semantics for the new element, and when the vector resizes, it will also use move constructors to transfer existing elements to the new memory (since C++11, vector prioritizes move semantics during resizing when possible).

An even simpler way to eliminate these extra copies entirely is to pre-reserve space in the vector before adding elements. Add this line right after creating the vector:

vec.reserve(5);

This allocates enough memory upfront for 5 elements, so the vector never needs to resize, and you won't see those extra copy constructor calls at all.

Second: Your code has a critical bug in the constructor!

Look closely at your normal constructor:

LargeTypeRaw(size_t initialSize = 10)
    : data{ new int[size] }, size{ initialSize }
{
    std::cout << "normal constructor called" << std::endl;        
}

In C++, member variables are initialized in the order they are declared in the class, not the order you write them in the initialization list. Your class declares data first, then size, so:

  1. data{ new int[size] } runs first—but size hasn't been initialized yet! You're using an uninitialized value to allocate memory, which is undefined behavior (it might seem to work now, but could crash or cause weird bugs later).

Fix this by using initialSize directly when allocating data (since the function parameter is guaranteed to be initialized):

LargeTypeRaw(size_t initialSize = 10)
    : size{ initialSize }, data{ new int[initialSize] }
{
    std::cout << "normal constructor called" << std::endl;        
}

This avoids the uninitialized variable issue entirely.

Quick recap

  • The copy constructor calls during push_back are vector's normal resizing behavior, but you can optimize with std::move or reserve().
  • Fix the constructor's initialization bug to avoid undefined behavior down the line.

内容的提问来源于stack exchange,提问作者Russell Butler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 10:05:26