在矢量中存储对象 [英] Storing objects in a vector

查看:64
本文介绍了在矢量中存储对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有用于测试存储对象概念的ff代码:


#include< vector>

#include< iostream>


使用命名空间std;


class MyClass {

public:

MyClass() {

cout<< 默认的cstor叫! << endl;

i = new int;

* i = 100;

}


MyClass( const MyClass& m){

cout<< 复制cstor叫! << endl;

this-> i = new int;

*(this-> i)= *(mi);

}


MyClass& operator =(const MyClass& m){

cout<< 被叫作业! << endl;

if(this!=& m){

MyClass tmp(m);

std :: swap(this-> ; i,tmp.i);

}

返回* this;

}


virtual~MyClass(){

cout<< dstor叫! << endl;

删除i;

}


int getVal(void){return * i; }

void setVal(int v){* i = v;}


private:

int * i;

};


int main(int argc,char * argv [])

{

MyClass mc;

std :: vector< MyClass> mv;


mv.push_back(mc);

cout<< 向量的元素0具有i值: << mv [0] .getVal()<<

endl;

cout<< 将i值设置为123 \ n ;

mv [0] .setVal(123);

cout<< 向量的元素0现在具有i值: << mv [0] .getVal()

<< endl;

mv.clear();

cout<< (清除后)矢量大小是: << mv.size()<<结束;


返回0;

}

这是控制台的输出(代码执行点位于

其中变量mc已被推回到向量中。


默认cstor被调用!

复制cstor调用!

复制cstor调用!

dstor调用!

我有以下问题:


1 )。为什么复制构造函数名为TWICE?

2)。为什么在mc之后调用的析构函数被推入向量?

3)。向量实现是否保证在以下情况下它将释放我的

(包含)对象:

(i)擦除()被调用

(ii )clear()被调用

(iii)向量超出范围?


- 因为向量存储要存储的项目的副本,它理应我

删除原始变量(其副本存储在

向量中),因为我不想要两个副本,浮动。和消费

资源 - 也许最好将指针存储到我的对象

而不是向量?在

a矢量中存储副本而不是原始项目似乎是一种非常低效/昂贵的处理方式

- 即:

$ b $双)。对象创建

ii)。制作对象的副本(向量存储副本不是原始的)

iii)。删除原始对象(所以只保留向量中的副本

) - 最大限度地减少资源消耗


它只是看起来不对..删除刚刚创建的对象(纯粹是为了制作副本)似乎很简单

傻...请说它不是这样的...


我错过了什么(如果有的话)?


期待一些富有洞察力的答案。非常感谢


Al

I have the ff code for testing the concept of storing objects:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "Default cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

MyClass( const MyClass& m) {
cout << "Copy cstor called !" << endl ;
this->i = new int ;
*(this->i) = *(m.i);
}

MyClass& operator=( const MyClass& m) {
cout << "Assignment called !" << endl ;
if (this != &m) {
MyClass tmp(m) ;
std::swap(this->i, tmp.i ) ;
}
return *this ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyClass> mv ;

mv.push_back(mc) ;
cout << "Element 0 of the vector has i value : " << mv[0].getVal() <<
endl ;
cout << "Setting i value to 123\n" ;
mv[0].setVal(123) ;
cout << "Element 0 of the vector now has i value : " << mv[0].getVal()
<< endl ;
mv.clear() ;
cout << "(After clear) size of vector is : " << mv.size() << endl ;

return 0;
}
Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !
I have the the following questions:

1). Why is the copy constructor called TWICE?
2). Why is the destructor called after mc has been pushed into the vector?
3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope?

- since a vector stores a copy of the item to be stored, it behooves me
to delete the original variables (the copies of which are stored in the
vector), since I do not want two copies, "floating about" and consuming
resources - maybe it would be better to store pointers to my object
instead in the vector?. Storing copies rather than the original items in
a vector seems quite an inefficient/expensive way of going about things
- i.e. :

i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption

It just dosen''t seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn''t so ...

What (if anything) am I missing?

Looking forward to some insightful answers. Many thanks

Al

推荐答案

Alfonso Morra写道:
Alfonso Morra wrote:
我有用于测试存储对象概念的ff代码:
#include< iostream>

使用命名空间std;

类MyClass {
公开:
MyClass(){
cout<< 默认的cstor叫! << endl;
i = new int;
* i = 100;
}

MyClass(const MyClass& m){
cout<< 复制cstor叫! << endl;
this-> i = new int;
*(this-> i)= *(m.i);
}

MyClass& operator =(const MyClass& m){
cout<< 被叫作业! << endl;
if(this!=& m){
MyClass tmp(m);
std :: swap(this-> i,tmp.i);
}
返回*这个;
}
虚拟~MyClass(){
cout<< dstor叫! << endl;
删除i;
}
int getVal(void){return * i; }
void setVal(int v){* i = v;}

私人:
int * i;
};

int main(int argc,char * argv [])
{
MyClass mc;
std :: vector< MyClass> mv;

mv.push_back(mc);
cout<< 向量的元素0具有i值: << mv [0] .getVal()<<
endl;
cout<< 将i值设置为123 \ n ;
mv [0] .setVal(123);
cout<< 向量的元素0现在具有i值: << mv [0] .getVal()
<< endl;
mv.clear();
cout<< (清除后)矢量大小是: << mv.size()<< endl;

返回0;
}

这是控制台的输出(代码执行点位于变量mc已经过的点) ;推回向量。

默认cstor调用!
复制cstor调用!
复制cstor调用!
dstor调用!


再次检查,上面的输出是错误的:

你跟踪所有对构造函数,赋值运算符的调用

和析构函数,即,前两个的调用次数

必须与析构函数调用平衡。


我有以下问题:
1)。为什么复制构造函数称为TWICE?
如果我编译并运行你的程序,那就不行了。

2)。为什么在mc之后调用的析构函数被推入向量?
因为push_back会创建一个副本。

3)。向量实现是否保证在以下情况下它将释放我的
(包含)对象:
(i)调用erase()
(ii)调用clear()
(iii) )矢量超出范围?
包含对象的析构函数将被调用,

除了最后一种情况外,矢量没有释放内存。

- 因为矢量存储了要存储的项目的副本,所以它应该是我的意思
删除原始变量(其副本存储在
向量中),因为我不想要两个副本,浮动。和消耗资源 - 也许最好将指针存储到我的对象
而不是在向量中?在向量中存储副本而不是原始项目似乎是一种非常低效/昂贵的处理方式
- 即:


再想一想:你怎么样?将原始项目存储在向量中?

您能为它提供伪代码吗?


如果类的复制结构很昂贵,您可以使用

std :: vector< Class *>作为STL容器,然而你需要

来提供一个包装类来处理复制,分配

和向量的破坏。

我)。对象创建
ii)。制作对象的副本(向量存储副本不是原始的)
iii)。删除原始对象(因此只保留向量中的副本) - 最大限度地减少资源消耗

它只是看起来不对...删除刚刚出现的对象
创建(纯粹是为了制作副本)看起来很简单
傻...请说它不是这样......

什么(如果有的话)我错过了吗?

期待一些富有洞察力的答案。非常感谢

Al
I have the ff code for testing the concept of storing objects:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "Default cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

MyClass( const MyClass& m) {
cout << "Copy cstor called !" << endl ;
this->i = new int ;
*(this->i) = *(m.i);
}

MyClass& operator=( const MyClass& m) {
cout << "Assignment called !" << endl ;
if (this != &m) {
MyClass tmp(m) ;
std::swap(this->i, tmp.i ) ;
}
return *this ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyClass> mv ;

mv.push_back(mc) ;
cout << "Element 0 of the vector has i value : " << mv[0].getVal() <<
endl ;
cout << "Setting i value to 123\n" ;
mv[0].setVal(123) ;
cout << "Element 0 of the vector now has i value : " << mv[0].getVal()
<< endl ;
mv.clear() ;
cout << "(After clear) size of vector is : " << mv.size() << endl ;

return 0;
}
Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !
Check again, the output above is wrong:
You trace all calls to constructors, assignment operator
and destructor, i.e., the number of calls to the first two
must balance with the destructor calls.


I have the the following questions:

1). Why is the copy constructor called TWICE? Not if I compile and run your program.
2). Why is the destructor called after mc has been pushed into the vector? Because push_back creates a copy.
3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope? The destructor of the "contained objects" will be called,
no memory is freed by the vector except for the last case.

- since a vector stores a copy of the item to be stored, it behooves me
to delete the original variables (the copies of which are stored in the
vector), since I do not want two copies, "floating about" and consuming
resources - maybe it would be better to store pointers to my object
instead in the vector?. Storing copies rather than the original items in
a vector seems quite an inefficient/expensive way of going about things
- i.e. :
Think again: How whould you store the original item in the vector?
Could you provide the pseudo code for it?

If the copy construction of a class is expensive, you may use
std::vector<Class*> as STL-container, however then you''ll need
to provide a wrapper class that takes care of copy, asssignment
and destruction of the vector.

i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption

It just dosen''t seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn''t so ...

What (if anything) am I missing?

Looking forward to some insightful answers. Many thanks

Al









Stephan Br?nnimann写道:


Stephan Br?nnimann wrote:
Alfonso Morra写道:
Alfonso Morra wrote:
我有用于测试存储对象概念的ff代码:
#include< vector>
#include< iostream>

使用命名空间std;

类MyClass {
公开:
MyClass(){
cout<< 默认的cstor叫! << endl;
i = new int;
* i = 100;
}

MyClass(const MyClass& m){
cout<< 复制cstor叫! << endl;
this-> i = new int;
*(this-> i)= *(m.i);
}

MyClass& operator =(const MyClass& m){
cout<< 被叫作业! << endl;
if(this!=& m){
MyClass tmp(m);
std :: swap(this-> i,tmp.i);
}
返回*这个;
}
虚拟~MyClass(){
cout<< dstor叫! << endl;
删除i;
}
int getVal(void){return * i; }
void setVal(int v){* i = v;}

私人:
int * i;
};

int main(int argc,char * argv [])
{
MyClass mc;
std :: vector< MyClass> mv;

mv.push_back(mc);
cout<< 向量的元素0具有i值: << mv [0] .getVal()<<
endl;
cout<< 将i值设置为123 \ n ;
mv [0] .setVal(123);
cout<< 向量的元素0现在具有i值: << mv [0] .getVal()
<< endl;
mv.clear();
cout<< (清除后)矢量大小是: << mv.size()<< endl;

返回0;
}

这是控制台的输出(代码执行点位于变量mc已经过的点) ;推回向量。

默认cstor调用!
复制cstor调用!
复制cstor调用!
dstor调用!
你跟踪所有对构造函数,赋值运算符
和析构函数的调用,
I have the ff code for testing the concept of storing objects:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "Default cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

MyClass( const MyClass& m) {
cout << "Copy cstor called !" << endl ;
this->i = new int ;
*(this->i) = *(m.i);
}

MyClass& operator=( const MyClass& m) {
cout << "Assignment called !" << endl ;
if (this != &m) {
MyClass tmp(m) ;
std::swap(this->i, tmp.i ) ;
}
return *this ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyClass> mv ;

mv.push_back(mc) ;
cout << "Element 0 of the vector has i value : " << mv[0].getVal() <<
endl ;
cout << "Setting i value to 123\n" ;
mv[0].setVal(123) ;
cout << "Element 0 of the vector now has i value : " << mv[0].getVal()
<< endl ;
mv.clear() ;
cout << "(After clear) size of vector is : " << mv.size() << endl ;

return 0;
}
Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !

Check again, the output above is wrong:
You trace all calls to constructors, assignment operator
and destructor,




那是什么用简单的英语表示?


即,前两个调用的次数必须与析构函数调用平衡。


嗯?



What does that mean in plain English ?

i.e., the number of calls to the first two must balance with the destructor calls.

Huh?


我有以下问题:

1)。为什么复制构造函数叫做TWICE?
如果我编译并运行你的程序就不行。

I have the the following questions:

1). Why is the copy constructor called TWICE?
Not if I compile and run your program.




嗯......



Hmm ....

2)。为什么在mc之后调用的析构函数被推入向量?
因为push_back创建了一个副本。
2). Why is the destructor called after mc has been pushed into the vector?
Because push_back creates a copy.




我不明白你在做什么,创建变量的副本

与删除变量不同 - 换句话说,

a副本由变量mc组成的事实并不能解释为什么它弗雷德。



I dont understand the point you''re making, creating a copy of a variable
is not the same as deleting the variable - in other words, the fact that
a copy is made of variable mc does not explain why it is fred.

3)。向量实现是否保证在以下情况下它将释放我的
(包含)对象:
(i)调用erase()
(ii)调用clear()
(iii) )向量是否超出范围?
3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope?



包含对象的析构函数将被调用,
除了最后一个案例之外,向量没有释放内存。



The destructor of the "contained objects" will be called,
no memory is freed by the vector except for the last case.




再一次,你的回答似乎不一致。如果

的析构函数包含对象"被调用,然后 - 内存被释放(这是

在我给出的包含对象MyClass的例子中肯定是真的)



Once again, your response seems inconsistent. If the destructor of
"contained objects" is invoked, then - memory is being freed (this is
certainly true in the example I gave of contained object MyClass)

- 因为矢量存储了要存储的项目的副本,所以我应该删除原始变量(其副本存储在
向量中),因为我不想要两个副本,浮动和消耗资源 - 也许最好将指针存储到我的对象
而不是在向量中?在向量中存储副本而不是原始项目似乎是一种非常低效/昂贵的处理方式
- 即:
- since a vector stores a copy of the item to be stored, it behooves me
to delete the original variables (the copies of which are stored in the
vector), since I do not want two copies, "floating about" and consuming
resources - maybe it would be better to store pointers to my object
instead in the vector?. Storing copies rather than the original items in
a vector seems quite an inefficient/expensive way of going about things
- i.e. :



再想一想:你怎么样?将原始项目存储在向量中?
你能为它提供伪代码吗?

如果一个类的副本构造很昂贵,你可以使用
std :: vector< ;类* GT;作为STL容器,然而你需要提供一个包装类来处理副本,分配和矢量的破坏。


Think again: How whould you store the original item in the vector?
Could you provide the pseudo code for it?

If the copy construction of a class is expensive, you may use
std::vector<Class*> as STL-container, however then you''ll need
to provide a wrapper class that takes care of copy, asssignment
and destruction of the vector.



这是公理化的。我想知道*什么*(如果有的话)资源管理

std :: vector提供开箱即用,所以我可以决定是否需要

滚动我自己的资源管理逻辑。


This is axiomatic. I wanted to know *what* (if any) resource management
std::vector provides "out of the box", so I can decide if I need to
"roll my own" resource management logic.

i)。对象创建
ii)。制作对象的副本(向量存储副本不是原始的)
iii)。删除原始对象(因此只保留向量中的副本) - 最大限度地减少资源消耗

它只是看起来不对...删除刚刚出现的对象
创建(纯粹是为了制作副本)看起来很简单
傻...请说它不是这样......

什么(如果有的话)我错过了吗?

期待一些富有洞察力的答案。非常感谢

Al
i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption

It just dosen''t seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn''t so ...

What (if anything) am I missing?

Looking forward to some insightful answers. Many thanks

Al







Alfonso Morra写道:
Alfonso Morra wrote:
我有用于测试存储对象概念的ff代码:

< vector>
#include< iostream>

使用namespace std;

class MyClass {
public:
MyClass(){
cout<< 默认的cstor叫! << endl;
i = new int;
* i = 100;
}

MyClass(const MyClass& m){
cout<< 复制cstor叫! << endl;
this-> i = new int;
*(this-> i)= *(m.i);
}

MyClass& operator =(const MyClass& m){
cout<< 被叫作业! << endl;
if(this!=& m){
MyClass tmp(m);
std :: swap(this-> i,tmp.i);
}
返回*这个;
}
虚拟~MyClass(){
cout<< dstor叫! << endl;
删除i;
}
int getVal(void){return * i; }
void setVal(int v){* i = v;}

私人:
int * i;
};

int main(int argc,char * argv [])
{
MyClass mc;
std :: vector< MyClass> mv;

mv.push_back(mc);
cout<< 向量的元素0具有i值: << mv [0] .getVal()
<< endl;
cout<< 将i值设置为123 \ n ;
mv [0] .setVal(123);
cout<< 向量的元素0现在具有i值: <<
mv [0] .getVal()<< endl;
mv.clear();
cout<< (清除后)矢量大小是: << mv.size()<< endl;

返回0;
}

这是控制台的输出(代码执行点位于变量mc已经过的点) ;推回向量。

默认cstor调用!
复制cstor调用!
复制cstor调用!
dstor调用!

我有以下问题:

1)。为什么复制构造函数称为TWICE?


不确定。我的实现似乎是一个临时的本地副本,然后将它复制到它最终的位置。

2)。为什么在mc之后调用的析构函数被推入向量?


临时副本超出范围。

3)。向量实现是否保证在以下情况下它将释放我的
(包含)对象:
(i)erase()被调用


是。

(ii)clear()被调用


应该等于:

vec.erase(vec.begin(),vec.end ())

(iii)向量超出范围?


是的。


但请记住,如果你使用指向你的对象的指针,那么它既是复制又删除的指针,而不是对象他们指向。

- 因为矢量存储了要存储的项目的副本,所以我应该删除原始变量(其副本存储在
vector),因为我不想要两个副本,浮动和消耗资源 - 也许最好将指针存储到我的对象
而不是在向量中?在向量中存储副本而不是原始项目似乎是一种非常低效/昂贵的处理事物的方式
- 即:

i)。对象创建
ii)。制作对象的副本(向量存储副本不是原始的)
iii)。删除原始对象(因此只保留向量中的副本) - 最大限度地减少资源消耗

它只是看起来不对...删除刚刚出现的对象
创建(纯粹是为了制作副本)看起来很简单
傻...请说它不是这样......

什么(如果有的话)我错过了吗?
I have the ff code for testing the concept of storing objects:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "Default cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

MyClass( const MyClass& m) {
cout << "Copy cstor called !" << endl ;
this->i = new int ;
*(this->i) = *(m.i);
}

MyClass& operator=( const MyClass& m) {
cout << "Assignment called !" << endl ;
if (this != &m) {
MyClass tmp(m) ;
std::swap(this->i, tmp.i ) ;
}
return *this ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyClass> mv ;

mv.push_back(mc) ;
cout << "Element 0 of the vector has i value : " << mv[0].getVal()
<< endl ;
cout << "Setting i value to 123\n" ;
mv[0].setVal(123) ;
cout << "Element 0 of the vector now has i value : " <<
mv[0].getVal() << endl ;
mv.clear() ;
cout << "(After clear) size of vector is : " << mv.size() << endl ;

return 0;
}
Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !
I have the the following questions:

1). Why is the copy constructor called TWICE?
Not sure. My implentation seems to make a temporary local copy, before copying it to where it will end up.
2). Why is the destructor called after mc has been pushed into the vector?
The temporary copy goes out of scope.
3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
Yes.
(ii) clear() is invoked
Should be equivelant to:
vec.erase(vec.begin(), vec.end())
(iii) vector goes out of scope?
Yes.

But remember that if you use pointers to your objects, it is the pointers it both copies AND deletes, not the objects they point to.
- since a vector stores a copy of the item to be stored, it behooves me
to delete the original variables (the copies of which are stored in the
vector), since I do not want two copies, "floating about" and consuming
resources - maybe it would be better to store pointers to my object
instead in the vector?. Storing copies rather than the original items in
a vector seems quite an inefficient/expensive way of going about things
- i.e. :

i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption

It just dosen''t seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn''t so ...

What (if anything) am I missing?




复制可能并不像你想象的那么昂贵,而且你不应该过早优化。


您可以使用引用计数指针来存储您的对象,如果它们真的要复制那么昂贵。看看提升智能指针:
http:// www。 boost.org/libs/smart_ptr/smart_ptr.htm


基准测试两种方法,但不要忘记像引用计数指针一样引入开销(计算时间)你复制,并在你访问时间接方向)


Ben

-

我不仅仅是一个数字。对很多人来说,我被称为弦乐......



The fact that copying probably isn''t as expensive as you think, and that you shouldn''t prematurely optimise.

You could use a reference counted pointer to store your objects if they really are that expensive to copy. Look at boost smart pointers:
http://www.boost.org/libs/smart_ptr/smart_ptr.htm

Benchmark both approaches, but don''t forget that something like a reference counted pointer introduces overhead too (counting when you copy, and indirection when you access)

Ben
--
I''m not just a number. To many, I''m known as a String...


这篇关于在矢量中存储对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆