c++中vector的内部工作
Internal working of a vector in C++?
我正在用c++做练习,但是我得到了意想不到的输出,我希望有人能解释一下。这个练习要求我创建一个名为rock的类,它有一个默认构造函数,一个复制构造函数和一个析构函数,它们都宣布自己为cout。
在main方法中,我将尝试按值将该类的成员添加到vector中:
vector<Rock> byValue;
Rock r1, r2, r3;
byValue.push_back(r1);
byValue.push_back(r2);
byValue.push_back(r3);
cout << "byValue populatednn";
我期望的输出(并在练习解决方案中显示)是:
Rock()
Rock()
Rock()
Rock(const Rock&)
Rock(const Rock&)
Rock(const Rock&)
byValue populated
~Rock()
~Rock()
~Rock()
~Rock()
~Rock()
~Rock()
但是我得到的输出是:
Rock()
Rock()
Rock()
Rock(const Rock&)
Rock(const Rock&)
Rock(const Rock&)
~Rock()
Rock(const Rock&)
Rock(const Rock&)
Rock(const Rock&)
~Rock()
~Rock()
byValue populated
~Rock()
~Rock()
~Rock()
~Rock()
~Rock()
~Rock()
谁能解释一下为什么似乎有对复制构造函数和析构函数的额外调用?
当vector被调整大小时,元素必须移动到它们的新位置。
正常
如果你调用
byValue.reserve(10);
在调用push_back
之前,多余的副本应该消失。
vector连续存储其元素。为了避免每次插入元素时总是重新分配内存,它确实分配了一堆内存。这就是为什么vector有两个关于其"大小"的方法:size()
表示存储的元素数量,capacity()
表示分配的内存量。
通常(但这取决于STL实现),它通过将其先前容量增加一倍来增长。当它分配更多内存时,由于数据必须连续存储(与list
相比),它必须移动其内部数据;STL复制数据,这就是为什么你有这么多调用构造函数/析构函数的原因。
如果你知道vector容器中要存储多少元素,你可以使用reserve
来表示首先应该分配多少内存。
std::vector
具有有限的内存来存储元素。您可以使用capacity
查询多少。您还可以使用reserve
方法告诉向量获取额外的内存。
当你将一个元素压入vector容器,而它的容量为零(它已经用完了所有额外的内存),它会分配一个新的更大的数组,并从原来的数组中复制元素。这就是所有额外副本的来源。
看看你的输出,看起来向量必须增长两次。如果将代码改为在压入任何对象之前调用reserve,则vector对象将永远不需要增长,也不会有额外的拷贝。
下面是一个详细的代码片段,展示了所有这些是如何结合在一起的:
- 访问说明符(私有/公共/受保护)如何在内部工作(限制成员访问)?
- 指向C++中成员的指针如何在内部工作?
- C 功能如何内部工作
- 自动参数如何在内部工作
- 函数指针仅在 main 内部工作
- 为什么SFINAE(enable_if)从类定义内部工作而不是从外部工作
- 如何将负数转换为更广泛的类型在内部工作
- std::remove_const 如何在<T>内部工作
- 冲刺的内部工作
- 安置新内部工作
- g++ 编译器的内部工作原理,用于傻瓜
- C++比较器保证和内部工作原理
- 在UTF-8内部工作,然后仅在Windows中需要时转换为UTF-16,是否存在任何危险
- 静态是如何在函数内部工作的
- 套接字api不能在类内部工作
- Setter不在类方法内部工作
- c++操作符的内部工作原理
- 我如何调试QTableView的内部工作
- c++中vector的内部工作
- 在哪里可以找到SciPy库中csr矩阵加法的内部工作