为什么在将项目插入地图时会有*三个*构造函数调用<>? [英] Why are there *three* constructor calls when inserting an item intoa map<>?

查看:74
本文介绍了为什么在将项目插入地图时会有*三个*构造函数调用<>?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



考虑附加的示例程序:将类型为A的对象插入地图< int,Am;中的
。除了构造函数调用之外,为什么''m [0];''调用

''''的复制构造函数?


当'A''报告中的构造函数和复制构造函数被称为
时。 ''whoami''只是分配给

类型''A''的每个对象的唯一标识符。该程序的输出是:


构造函数0

构造函数1

复制缺点2来自1

copy cons 3 from 2

析构函数2

析构函数1

赋值3来自0

析构函数0

析构函数3

我希望一个构造函数调用足以在地图中创建一个

对象。为什么有必要复制两次最初的

创建的对象?


我希望得到以下输出:


构造函数0

构造函数1

赋值1从0

析构函数0

析构函数1

(我用g ++和数字火星编译器试过这个。)


- Szabolcs


-----


#include< iostream>

#include< map>


使用namespace std;


int counting_As = 0;


A级{

int whoami;

public:

A(){

whoami = counting_As ++;

cout<< 构造函数 << whoami<<结束;

}

~A(){

cout<< 析构函数 << whoami<<结束;

}

A(const A& p){

whoami = counting_As ++;

cout< ;< 复制缺点 << whoami<< "来自 << p.whoami<<结束;

}

A& operator =(const A& p){

cout<< 赋值 << whoami<< "来自 << p.whoami<<结束;

返回(* this);

}

};


int main( ){

map< int,Am;

A a;

m [0] = a;

返回0;

}


Consider the attached example program: an object of type ''A'' is inserted
into a ''map<int, Am;''. Why does ''m[0];'' call the copy constructor of
''A'' twice in addition to a constructor call?

The constructors and copy constructors in ''A'' report when they are
called. ''whoami'' is just a unique identifier assigned to every object of
type ''A''. The output of the program is:

constructor 0
constructor 1
copy cons 2 from 1
copy cons 3 from 2
destructor 2
destructor 1
assignment 3 from 0
destructor 0
destructor 3

I would expect one constructor call to be sufficient for creating an
object inside the map. Why is it necessary to copy twice the initially
created object?

I''d expect the following output:

constructor 0
constructor 1
assignment 1 from 0
destructor 0
destructor 1

(I tried this with both g++ and the digital mars compiler.)

-- Szabolcs

-----

#include <iostream>
#include <map>

using namespace std;

int counting_As = 0;

class A {
int whoami;
public:
A() {
whoami = counting_As++;
cout << "constructor " << whoami << endl;
}
~A() {
cout << "destructor " << whoami << endl;
}
A(const A &p) {
whoami = counting_As++;
cout << "copy cons " << whoami << " from " << p.whoami << endl;
}
A & operator = (const A &p) {
cout << "assignment " << whoami << " from " << p.whoami << endl;
return (*this);
}
};

int main() {
map<int, Am;
A a;
m[0] = a;
return 0;
}

推荐答案

SzabolcsHorvát写道:
Szabolcs Horvát wrote:

我希望一个构造函数调用足以在地图中创建一个

对象。为什么有必要复制两次最初的

创建的对象?


我希望得到以下输出:


构造函数0

构造函数1

赋值1从0

析构函数0

析构函数1
I would expect one constructor call to be sufficient for creating an
object inside the map. Why is it necessary to copy twice the initially
created object?

I''d expect the following output:

constructor 0
constructor 1
assignment 1 from 0
destructor 0
destructor 1



您需要至少复制一次才能将其放入地图中,否则

您的容器不包含任何内容,它只是引用

自动内存(堆栈)上的一个对象。

我不知道为什么它会复制两次。

You need to copy it at least one time to put it into the map, otherwise
your container doesn''t contain anything, it just references an object on
automatic memory (the stack).
I don''t know why it copies it two times though.


loufoque写道:
loufoque wrote:

>

您需要至少复制一次才能将其放入地图中,否则

您的容器不包含任何东西,它只是引用了一个对象

自动内存(堆栈)。

我不喜欢不知道为什么它会复制两次。
>
You need to copy it at least one time to put it into the map, otherwise
your container doesn''t contain anything, it just references an object on
automatic memory (the stack).
I don''t know why it copies it two times though.



实际上你根本不需要复制构造函数调用,因为map中的operator []

已经创建了一个具有默认值的对象(' '构造函数1''
输出中的
),因此赋值('赋值1从0'')应该足够



我不明白这些复制构造函数调用是否是必需的(它们存在于至少两个STL实现中);可以

map<没有他们的工作?

Actually you need no copy constructor calls at all, because operator []
in map already creates an object with a default value (''constructor 1''
in the output), so the assignment (''assignment 1 from 0'') should be
sufficient.

What I don''t understand whether these copy constructor calls are a
necessity (they are present in at least two STL implementations); could
map<work without them?


SzabolcsHorvát写道:
Szabolcs Horvát wrote:

考虑附加的示例程序:将类型为''A'的对象插入到''map< int,Am;''中。
。为什么'm [0];''除了构造函数调用之外,还要两次调用

''''的复制构造函数?
Consider the attached example program: an object of type ''A'' is inserted
into a ''map<int, Am;''. Why does ''m[0];'' call the copy constructor of
''A'' twice in addition to a constructor call?


int main(){

map< int,Am;

A a;

m [0] = a;

返回0;

}
int main() {
map<int, Am;
A a;
m[0] = a;
return 0;
}



此行为取决于实现,并非所有编译器设置

或库实现都会给您相同的结果。也就是说,

使用operator []在关联容器上进行首次插入是非常有效的。它就是这样的。


V& map :: operator [K const& i] {

iterator _ret = this-> find(i);

if(_ret == this-> end( )){//未找到

V _tmp; //构造函数1

//映射存储std :: pair< const K,Vunder引擎盖

std :: pair _ins(i,_tmp); //从1复制构造2

_ret = this-> insert(_ins); //复制构造3从2

//插入返回它放置副本的位置

}

V& _valret = _ret-> second; //该对的V部分

返回_valret;

//析构函数2

// destrutor 1

}

现在你有0号(A a)和3号活着。这就是为什么你现在看到
从0到3的分配。

希望有帮助

This behavior is implementation dependent, and not all compiler setting
or library implementation will give you the same results. That said,
using operator[] for first insertions on the associative containers is
not terribly efficient. It goes something like this.

V& map::operator[K const&i]{
iterator _ret= this->find(i);
if(_ret==this->end()){//not found
V _tmp; //constructor 1
// map stores std::pair<const K,Vunder the hood
std::pair _ins(i,_tmp); // copy construct 2 from 1
_ret=this->insert(_ins); // copy construct 3 from 2
//insert returns where it placed the copy
}
V& _valret=_ret->second;// the V part of the pair
return _valret;
//destructor 2
//destrutor 1
}
Now you have number 0 (the A a) and number 3 alive. And this is why you
now see assigment from 0 to 3.
Hope that helps


这篇关于为什么在将项目插入地图时会有*三个*构造函数调用&lt;&gt;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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