【发布时间】:2014-05-26 03:35:48
【问题描述】:
在编写一些将数据结构(部分)加载到图形内存中的代码时,我对这种意外行为感到惊讶。
我已将代码简化为以下内容:
#include <iostream>
#include <vector>
using namespace std;
struct Data{
int data;
Data(int x){
data = x;
cout<<"+ Data"<<endl;
}
~Data(){cout<<"- Data"<<endl;}
};
struct Handle{
// imagine some handles to video memory here
Handle(Data d){
// (upload data to video memory)
cout<<"+ Handle"<<endl;
}
~Handle(){
// (deallocate the data from video memory)
cout<<"- Handle"<<endl;
}
};
int main(){
vector<Handle> container;
cout<<"start"<<endl;
for(int i=0; i<4; i++){
container.emplace_back(Data(i));
cout<<endl;
}
cout<<"end"<<endl;
}
我的预期:
start
+ Data
+ Handle
- Data
+ Data
+ Handle
- Data
+ Data
+ Handle
- Data
+ Data
+ Handle
- Data
end
-Handle
-Handle
-Handle
-Handle
我得到了什么:
start
+ Data
+ Handle
- Data
- Data
+ Data
+ Handle
- Data
- Handle
- Data
+ Data
+ Handle
- Data
- Handle
- Handle
- Data
+ Data
+ Handle
- Data
- Data
end
- Handle
- Handle
- Handle
- Handle
谁能解释这种行为?
【问题讨论】:
-
你应该声明一个复制构造函数,这样你就可以真正追踪创建了多少对象......
-
Handles 构造函数中有一个未使用的参数。你指望过吗?另外,container.emplace_back(i);,这样您就不会做不必要的临时工作。 -
emplace_back是 C++11.. 现在不需要它,因为在 C++11 中没有使用 push_back 临时创建:void push_back(T&& value); -
@Macmade 谢谢!这解释了额外的析构函数调用。
-
cppguy 回答答案中的附加数据副本。我添加这条评论是为了提到额外的句柄可以通过在向量上使用reserve() 来消除,所以它不需要调整大小。
标签: c++ constructor destructor instantiation raii