C++ 我想不出有多少复制品

C++ 我想不出有多少复制品,c++,constructor,destructor,C++,Constructor,Destructor,默认构造之后发生了什么?为什么这把尺子创建了太多的副本并销毁了它们?这里有什么问题?std::vector管理自己的内存。这意味着std::vector只存储对象的副本,这意味着对象必须具有有意义的副本构造函数(和赋值运算符,但这是另一个问题) 当一个向量的析构函数被调用时,该向量所持有的内存被释放。当对象被删除时(通过擦除、弹出、清除或向量的析构函数),std::vector也会调用对象的析构函数。std::vector管理自己的内存。这意味着std::vector只存储对象的副本,这意味着对

默认构造之后发生了什么?为什么这把尺子创建了太多的副本并销毁了它们?这里有什么问题?

std::vector管理自己的内存。这意味着std::vector只存储对象的副本,这意味着对象必须具有有意义的副本构造函数(和赋值运算符,但这是另一个问题)


当一个向量的析构函数被调用时,该向量所持有的内存被释放。当对象被删除时(通过擦除、弹出、清除或向量的析构函数),std::vector也会调用对象的析构函数。

std::vector管理自己的内存。这意味着std::vector只存储对象的副本,这意味着对象必须具有有意义的副本构造函数(和赋值运算符,但这是另一个问题)


当一个向量的析构函数被调用时,该向量所持有的内存被释放。std::vector在删除对象时(通过擦除、弹出、清除或向量的析构函数)也会调用对象的析构函数。

基本上,如果向量已满,而您正在推送一个元素,则向量需要调整大小。因此,当您将
Ruler
推到向量上时,将创建一个大小为
sizeof(items)
的数组,并复制数据(第一个复制构造函数调用
Ruler
)。然后在向量上按
Pencil
(第一次复制构造函数调用
Pencil
),但是向量内存不足,因此分配一个新数组,其大小是以前大小的两倍
2*sizeof(items)
,并将旧数组复制到新数组(第二次复制构造函数调用
标尺
)然后旧数组被销毁(第一个析构函数在旧数组中调用
标尺
),依此类推…

基本上,如果一个向量已满,而您正在推一个元素,那么该向量需要调整大小。因此,当您将
Ruler
推到向量上时,将创建一个大小为
sizeof(items)
的数组,并复制数据(第一个复制构造函数调用
Ruler
)。然后在向量上按
Pencil
(第一次复制构造函数调用
Pencil
),但是向量内存不足,因此分配一个新数组,其大小是以前大小的两倍
2*sizeof(items)
,并将旧数组复制到新数组(第二次复制构造函数调用
标尺
)并且旧数组被破坏(在第一个析构函数中调用了<代码> >旧的数组中的标尺< /代码>等等…

< p>您的“默认构造函数”采用一个参数,因此,不是C++意义上的默认构造函数:默认构造函数可以被调用而不需要任何参数。 关于你的问题,似乎顺序如下:

  • 最初,所有对象都被构造
  • 有一个
    标尺
    对象的副本将其插入
    学校
    向量
  • 插入
    铅笔
    时,首先复制此对象,但
    学校
    向量中显然没有足够的空间:将
    铅笔
    对象复制到新分配的位置,然后复制
    标尺
    ,并销毁原始空间
  • 当插入
    书籍
    时,同样的顺序发生:将
    书籍
    复制到新位置,然后将
    标尺
    铅笔
    也复制到新位置
  • 最后,所有对象都被销毁
  • 序列在某种意义上有些混乱,因为std::vector通常不会这样做:它通常在一开始就创建一个小数组,可以容纳多个元素。看起来,使用的实现一开始只有一个
    capacity()
    ,然后将容量增加一倍。您可以通过查看调用
    school.capacity()
    之间的
    school.capacity()
    来验证此行为:只要
    capacity()
    增加,底层数组就会增加

    <> P>考虑到你正在分配内存,你可能需要考虑一个移动构造函数,它移动存储的内存,而不是分配一个新的数组来容纳一个拷贝,然后只是<代码>删除< /代码>原件。移动构造函数的外观如下所示:

    Default ctor Ruler  @0x62ff1c
    Default ctor Pencil     @0x62ff18
    Default ctor Book   @0x62ff14
    Default ctor Notebook   @0x62ff10
    Default ctor Sharpener  @0x62ff0c
    Copy ctor Ruler     @0x9cd1d0
    Copy ctor Pencil    @0x9cd504
    Copy ctor Ruler     @0x9cd500
    dtor    Ruler   @0x9cd1d0
    Copy ctor Book  @0x9c0510
    Copy ctor Ruler     @0x9c0508
    Copy ctor Pencil    @0x9c050c
    dtor    Ruler   @0x9cd500
    dtor    Pencil  @0x9cd504
    dtor    Ruler   @0x9c0508
    dtor    Pencil  @0x9c050c
    dtor    Book    @0x9c0510
    dtor    Sharpener   @0x62ff0c
    dtor    Notebook    @0x62ff10
    dtor    Book    @0x62ff14
    dtor    Pencil  @0x62ff18
    dtor    Ruler   @0x62ff1c
    

    您的“默认构造函数”采用一个参数,因此,不是C++意义上的默认构造函数:默认构造函数可以被调用而不需要任何参数。 关于你的问题,似乎顺序如下:

  • 最初,所有对象都被构造
  • 有一个
    标尺
    对象的副本将其插入
    学校
    向量
  • 插入
    铅笔
    时,首先复制此对象,但
    学校
    向量中显然没有足够的空间:将
    铅笔
    对象复制到新分配的位置,然后复制
    标尺
    ,并销毁原始空间
  • 当插入
    书籍
    时,同样的顺序发生:将
    书籍
    复制到新位置,然后将
    标尺
    铅笔
    也复制到新位置
  • 最后,所有对象都被销毁
  • 序列在某种意义上有些混乱,因为std::vector通常不会这样做:它通常在一开始就创建一个小数组,可以容纳多个元素。看起来,使用的实现一开始只有一个
    capacity()
    ,然后将容量增加一倍。您可以通过查看调用
    school.capacity()
    之间的
    school.capacity()
    来验证此行为:只要
    capacity()
    增加,底层数组就会增加

    <> P>考虑到你正在分配内存,你可能需要考虑一个移动构造函数,它转移存储的内存,而不是
    Default ctor Ruler  @0x62ff1c
    Default ctor Pencil     @0x62ff18
    Default ctor Book   @0x62ff14
    Default ctor Notebook   @0x62ff10
    Default ctor Sharpener  @0x62ff0c
    Copy ctor Ruler     @0x9cd1d0
    Copy ctor Pencil    @0x9cd504
    Copy ctor Ruler     @0x9cd500
    dtor    Ruler   @0x9cd1d0
    Copy ctor Book  @0x9c0510
    Copy ctor Ruler     @0x9c0508
    Copy ctor Pencil    @0x9c050c
    dtor    Ruler   @0x9cd500
    dtor    Pencil  @0x9cd504
    dtor    Ruler   @0x9c0508
    dtor    Pencil  @0x9c050c
    dtor    Book    @0x9c0510
    dtor    Sharpener   @0x62ff0c
    dtor    Notebook    @0x62ff10
    dtor    Book    @0x62ff14
    dtor    Pencil  @0x62ff18
    dtor    Ruler   @0x62ff1c
    
    items::items(items&& other)
        : name(other.name) {
        this->name = nullptr;
    }