C++ 动态数组vector

文章探讨了C++中动态数组vector的工作原理,特别是当元素数量超过容量时自动扩容的过程,以及由此产生的对象拷贝。推荐直接存储对象而非指针,以提高效率。通过示例展示了Vertex结构体,解释了push_back操作导致的多次拷贝,并提出了使用emplace_back和reserve来减少拷贝、提高性能的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态数组的原理

当元素个数比本身的容器容量多时,会自动创建一个更大的容器,并将原容器中的元素全都拷贝进去,然后删掉原容器。

以下面结构体为例

struct Vertex
{
    float x, y, z;
};

ostream& operator << (ostream& stream, const Vertex& vertex)
{
    stream << vertex.x << ", " << vertex.y << ", " << vertex.z;
    return stream;
    
}

vector基本操作

构造这个结构体的动态数组:(<>用来指定类型,可以是原始数据类型)

vector<Vertex> vertices;
vector<Vertex*> vertices;

一般情况下推荐直接存对象本身,迫不得已存指针类型。vector是连续空间的线性存储,存对象时,对其中元素的遍历或修改等操作会更快。

遍历方式:
两种都可,但注意第二种要引用,否则每次都会创建一个v并拷贝对应元素。

for (int i = 0; i < vertices.size(); i++)
	cout << vertices[i] << endl;
for (Vertex& v: vertices)
    cout << v << endl;

其他操作:

# 添加元素,{1,2,3}调用了默认的构造函数
vertices.push_back({1, 2, 3});
# 删除索引是1的元素
vertices.erase(vertices.begin()+1);
# 清空数组
vertices.clear();

对于使用该数组的函数:参数一定要使用引用,否则将拷贝整个数组

void Func(const vector<Vertex>& vertices)
{
    
}

vector优化

优化的目的就是减少拷贝。
将上述Vertex类添加拷贝构造函数的输出,通过单步调试可以查看拷贝情况:

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)
    {
        cout<< "copied" << endl;
    }
};

int main()
{
    vector<Vertex> vertices;
    vertices.push_back(Vertex(1, 2, 3));
    vertices.push_back(Vertex(4, 5, 6));
    vertices.push_back(Vertex(7, 8, 9));
 	// 一共输出了6次copied
}

为什么会输出6次copied?

  1. 上述添加元素使用的是push_back,也就是将创建好的对象放入数组,这意味着首先要在main中创建了一个对象,再将他拷贝到数组中。
  2. 调试过程中可以发现数组的大小一开始是0,然后是1,2,3,也就是数组的大小是动态调整的,这需要将原来数组的元素拷贝到新数组,然后删除原数组。

因此整个过程为:

  1. 首先创建了一个size为0的vector。
  2. 创建size为1的vector,删除size为0的vector。创建一个Vertex对象(1,2,3),将他拷贝到vector中。总计1次拷贝
  3. 创建size为2的vector,将size为1的vector中的Vertex(1,2,3)复制到size为2的vector中,删除size为1的vector。创建Vertex对象(4,5,6),将其拷贝到size为2的vector中。总计2次拷贝。
  4. 同理,总计3次拷贝。

解决办法

  1. 使用emplace_back()在vector内直接创建对象,参数为构造函数所需的参数列表
  2. 使用reserve()为vector预先指定一个大小
vector<Vertex> vertices;
vertices.reserve(3);
vertices.emplace_back(1, 2, 3);
vertices.emplace_back(4, 5, 6);
vertices.emplace_back(7, 8, 9);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值