Vector以一种假装数组元素是向量本身的成员的方式包装它的数组。这就是为什么你不能修改const向量的数组元素。该向量还允许您访问其数组元素的地址。但是,如果我得到一个指向矢量数组元素的指针(它是矢量本身的一个元素),然后我分配给矢量,我的指针就不再被定义为指向矢量的一个元素。 push_back()
或类似的东西使指针无效是有道理的,因为没有人说push_back()
没有对向量的元素做一些荒谬的事情。
任何常规类型都会让我指向其元素的指针在赋值后保持有效。那么,并不是没有解决办法,但是不会使矢量成为非常规类型吗?
std::string
以及标准中的许多其他列表/存储类型也是如此。
编辑:当我说具体类型时意味着常规类型。
编辑,还有一点:所以,在c中,如果你有一个指向结构成员的指针,那么分配给那个结构就不能改变对象的位置,因为你不可能假装数组元素是结构的一部分。但是,在向量中,此规则被破坏。成员是对象的成员,因为它实际上与相同的对象名称相关联,并且始终在对象被销毁之前。因此,没有常规操作应该能够改变这样的事情。
答案 0 :(得分:3)
C ++中常规类型的概念来自Stepanov的编程元素。它基本上是一种类型的合理/有用概念的列表。例如,它应该支持相等,赋值和赋值应该具有post-condition变量与原始变量相等的post条件(当然,这是复制赋值而不是移动赋值)。
但是,规律性不包括您所描述的概念。具体是一个完全不同的东西,它基本上只是任何实际可以实例化的类,即没有纯虚方法。
Stepanov确实有一个与你所描述的相关的分类。我没有方便地使用我的副本,但我认为他将其称为内部对外部:它是一个问题,即包含该类型实例的位是否实际包含该值的所有信息。向量是外部的,因为通常构成向量的三个指针本身并没有完全描述它,堆上的东西也是向量表示的一部分,即使它不包含&# 34;内部"实际的矢量实例。您要描述的问题是因为矢量是外部的。每当你获取直接指向类型外部部分的指针,然后对该类型执行操作时,这些指针可能会失效。但是,像int这样的简单成员的结构是内部的,所有信息都包含在结构本身中。这会导致行为上的差异。
如果你想要一个动态大小的数组类型,你基本上必须使用堆,并且使用堆意味着你的类型将是外部的,此时你可以自己解决这些问题。这就是为什么所有标准容器都有详细描述其迭代器何时无效的原因。