vector在发生内存重新分配时,会对原有的元素调用析构函数吗?

nbb 2003-12-07 02:05:00
vector在发生内存重新分配时,会重新分配内存,并拷贝原有的元素到新内存区,然后删除原有的内存,那么它会对这些原来的元素调用析构函数吗?
...全文
250 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
begginginstorm 2003-12-08
  • 打赏
  • 举报
回复
写成这样可能更好理解:

class Foo
{
static int iCount ;
int id;
public:
Foo(){ ++iCount; id = iCount; cout<<"Foo()\t"<<iCount<<endl; }
Foo(const Foo& copy)
{
this->id = copy.id;
cout << "Copy construction, id:" << this->id << endl;
}
~Foo(){ cout<<"~Foo()\t"<<id<<endl; }
};

int Foo::iCount = 0;



int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
vector< Foo > fv;
fv.reserve(1);

Foo f1,f2,f3;
cout << "Insert first:" << endl;
fv.push_back(f1);
cout << "Insert second:" << endl;
fv.push_back(f2);
cout << "Insert third:" << endl;
fv.push_back(f3);

cout << "Operation has completed" << endl;

return 0;
}

输出结果:
Foo() 1
Foo() 2
Foo() 3
Insert first:
Capacity:1
Copy construction, id:1
Insert second:
Capacity:1
Copy construction, id:1
Copy construction, id:2
~Foo() 1
Insert third:
Capacity:2
Copy construction, id:1
Copy construction, id:2
Copy construction, id:3
~Foo() 1
~Foo() 2
Operation has completed
~Foo() 3
~Foo() 2
~Foo() 1
~Foo() 1
~Foo() 2
~Foo() 3

可以看出vector在发现自身空间不足时,首先申请了一块更大的空间(一般2倍),然后调用拷贝构造函数拷贝已有元素,然后调用析构释放存在于小空间上的元素。

如果你的元素没有特别的要求,那么不必提供拷贝构造,这是编译器会自动为你生成一个bit-wise的拷贝构造函数,也就是按位拷贝(浅拷贝);如果你的元素内部有比较特殊的成员变量(比如handle,指针,智能指针之类等),那你就必须根据这些特殊的成员变量提供一个适合自己的拷贝构造函数,以防止在拷贝构造/析构的过程中信息丢失或数据错误。
Yssss1980 2003-12-08
  • 打赏
  • 举报
回复
由此可见reserve函数确实有用
把reserve(1)改为reserve(3),结果是这样的

/**result:
Foo() 1
Foo() 2
Foo() 3
Foo() 4
Foo() 5
Foo() 6
~Foo() 3
~Foo() 2
~Foo() 1
~Foo() 4
~Foo() 5
~Foo() 6
*/
Yssss1980 2003-12-08
  • 打赏
  • 举报
回复
把楼上程序改了改,增加了一个拷贝ctor,发现居然一共产生了9个Foo
#include <vector>
#include <iostream>
using namespace std;

class Foo
{
static int iCount ;
int id;
public:
Foo(){ ++iCount; id = iCount; cout<<"Foo()\t"<<iCount<<endl; }
Foo(const Foo & other){++iCount; id = iCount; cout<<"Foo()\t"<<iCount<<endl;}
~Foo(){ cout<<"~Foo()\t"<<id<<endl; }
};

int Foo::iCount = 0;

int main()
{
vector< Foo > fv;
fv.reserve(1);

Foo f1,f2,f3;
fv.push_back(f1);
fv.push_back(f2);
fv.push_back(f3);
return 0;
}

/**result:
Foo() 1
Foo() 2
Foo() 3
Foo() 4
Foo() 5
Foo() 6
~Foo() 4
Foo() 7
Foo() 8
Foo() 9
~Foo() 5
~Foo() 6
~Foo() 3
~Foo() 2
~Foo() 1
~Foo() 7
~Foo() 8
~Foo() 9
*/
cityyokel 2003-12-07
  • 打赏
  • 举报
回复
#include <vector>
#include <iostream>
using namespace std;

class Foo
{
static int iCount ;
int id;
public:
Foo(){ ++iCount; id = iCount; cout<<"Foo()\t"<<iCount<<endl; }
~Foo(){ cout<<"~Foo()\t"<<id<<endl; }
};

int Foo::iCount = 0;

int main()
{
vector< Foo > fv;
fv.reserve(1);

Foo f1,f2,f3;
fv.push_back(f1);
fv.push_back(f2);
fv.push_back(f3);

return 0;
}

结果是:
Foo() 1
Foo() 2
Foo() 3
~Foo() 1
~Foo() 2
~Foo() 1
~Foo() 2
~Foo() 3
~Foo() 3
~Foo() 2
~Foo() 1
~Foo() 1
~Foo() 2
~Foo() 3

看一下就知道了吧
Wolf0403 2003-12-07
  • 打赏
  • 举报
回复
因为没有传说中的 move-ctor,vector 的内存重新分配过程(一般是分配一块 1.5 倍大小的空间),然后用 copy-ctor + dtor 进行复制。
nbb 2003-12-07
  • 打赏
  • 举报
回复
偶也同意sakurar的观点,可是偶接触的标准库好像是要调用的! 真TMD的不爽: 偶在容器的元素中分配了HANDLE,在析构时释放,如果扩容时要对原元素调用析构函数,偶的HANDLE就完了!
sakurar 2003-12-07
  • 打赏
  • 举报
回复
为什么不亲自试试?!
我认为这种扩容不会调用构析函数。如果是我写这个容器,我情愿把是否释放的权利交给用户来决定。而且的确也没必要进行释放。因为你不知道调用一个未知类型的析构函数会发生什么。

想不调构析函数就释放了内存那还不容易?作为模板容器,直接申请与释放基础类型的、所需要尺寸的内存段就是了。
ntxs 2003-12-07
  • 打赏
  • 举报
回复
同意楼上
nirvana_li 2003-12-07
  • 打赏
  • 举报
回复
vector发生内存重新分配的时候,先建立一个比原有内存单元大2倍的内存单元,然后把原有的vector的一个副本拷贝到新的内存单元中,然后将原有的内存单元撤消,这个动作应该会调用它的析构函数,不然怎么消除原来的内存单元呢?

24,855

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧