关于vector构造函数的问题

lijun2516 2008-08-01 01:54:44
为什么A构造了四次?(vs2005编译)
class A{
public:
A(){std::cout<<"default constructor"<<std::endl;}
};


int _tmain(int argc, _TCHAR* argv[])
{
std::vector<A> x(3);
A a1,a2,a3;
x.push_back(a1);
x.push_back(a2);
x.push_back(a3);
return 0;
}
...全文
1123 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
haofang666777 2011-10-28
  • 打赏
  • 举报
回复
学习了[Quote=引用 17 楼 steedhorse 的回复:]
调用push_back时有三次拷贝构造,原因跟push_back的内部实现有关。
push_back的参数虽然是引用类型的,但为了避免在将vector中的已有元素push_back进vector时产生bug,它内部还是先拷贝了一份。
这主要是为了避免像下面这样使用时产生bug:

vector<A> v(3);
v.push_back(v[0]);
因为push_back有可能引起内存……
[/Quote]
xiazhan110 2011-10-28
  • 打赏
  • 举报
回复
学习。。。。。。。。。。。。。。。。。。
晨星 2008-08-02
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 lijun2516 的回复:]
终于明白了,可是这对效率会有很大影响啊
[/Quote]
唉,只能说“通用”必然有代价。
你总不能让STL的实现者在文档里写上一条“禁止基于内部引用做再次插入”吧?毕竟这看起来并不是一个很合理的要求。而且万一有人没看到这句话,出了问题,岂不是又要调试半天?而且最讨厌的事情就是错误调试需要跟综到库代码里去。。。
guzhilei1986 2008-08-02
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 stone_clock 的回复:]
int main(int argc, char* argv[])
{
std::vector <A> x(3); // 1次默认构造,3次拷贝构造,1次析构//没有听说过,学习了
A a1; // 1次默认构造
A a2; // 1次默认构造
A a3; // 1次默认构造
x.push_back(a1); // 1次拷贝构造
x.push_back(a2); // 1次拷贝构造
x.push_back(a3); // 1次拷贝构造

return 0;
}

[/Quote]
guzhilei1986 2008-08-02
  • 打赏
  • 举报
回复
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
class A{
public:
A(){std::cout <<"default constructor" <<std::endl;}
};


int main()
{
std::vector <A> x(3);
A a1,a2,a3;
x.push_back(a1);
x.push_back(a2);
x.push_back(a3);
std::cout<<x.size()<<std::endl;//这里输出一个6,里面有六个元素,为什么?
getchar();
getchar();
return 0;
}
lijun2516 2008-08-02
  • 打赏
  • 举报
回复
终于明白了,可是这对效率会有很大影响啊
Vegertar 2008-08-02
  • 打赏
  • 举报
回复
学习
lijun2516 2008-08-01
  • 打赏
  • 举报
回复
为什么第一个x.push(a1)调用了多次copy constructor
太乙 2008-08-01
  • 打赏
  • 举报
回复
x.push_back(a1);
x.push_back(a2);
x.push_back(a3);


这几个不好解释~~
太乙 2008-08-01
  • 打赏
  • 举报
回复



//这个完整重贴下!
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A()
{
std::cout <<"default constructor" <<std::endl;
}
A(const A & a)
{
cout<<"Copyconstructor"<<endl;
}
~A()
{
cout<<"Desconstructor"<<endl;
}
};


int main(int argc, char* argv[])
{
std::vector <A> x(3); //以class A为参数类型 需要调通一次默认的构造函数

// A a1,a2,a3; //构造三个对象,调用三次构造函数
//x.push_back(a1);
//x.push_back(a2);
//x.push_back(a3);
getchar();
return 0;
}
/*输出:
default constructor
Copyconstructor
Copyconstructor
Copyconstructor
Desconstructor
*/









//这个完整重贴下!
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A()
{
std::cout <<"default constructor" <<std::endl;
}
A(const A & a)
{
cout<<"Copyconstructor"<<endl;
}
~A()
{
cout<<"Desconstructor"<<endl;
}
};


int main(int argc, char* argv[])
{
std::vector <A> x(3); //以class A为参数类型 需要调通一次默认的构造函数

A a1,a2,a3; //构造三个对象,调用三次构造函数
//x.push_back(a1);
//x.push_back(a2);
//x.push_back(a3);
getchar();
return 0;
}
/*

default constructor
Copyconstructor
Copyconstructor
Copyconstructor
Desconstructor
default constructor
default constructor
default constructor



*/








//这个完整重贴下!
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A()
{
std::cout <<"default constructor" <<std::endl;
}
A(const A & a)
{
cout<<"Copyconstructor"<<endl;
}
~A()
{
cout<<"Desconstructor"<<endl;
}
};


int main(int argc, char* argv[])
{
std::vector <A> x(3); //以class A为参数类型 需要调通一次默认的构造函数

A a1,a2,a3; //构造三个对象,调用三次构造函数
x.push_back(a1);
x.push_back(a2);
x.push_back(a3);
getchar();
return 0;
}

/*

default constructor
Copyconstructor
Copyconstructor
Copyconstructor
Desconstructor
default constructor
default constructor
default constructor
Copyconstructor
Copyconstructor
Copyconstructor
Copyconstructor
Desconstructor
Desconstructor
Desconstructor
Copyconstructor
Copyconstructor
Copyconstructor
Copyconstructor
Copyconstructor
Desconstructor
Desconstructor
Desconstructor
Desconstructor
Copyconstructor


*/

太乙 2008-08-01
  • 打赏
  • 举报
回复
我看不是那么简单啊!
太乙 2008-08-01
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 wangdeqie 的回复:]
C/C++ code
//这个完整重贴下!
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A()
{
std::cout <<"default constructor" <<std::endl;
}
A(const A & a)
{
cout<<"Copyconstructor"<<endl;
}
~A()
{
cout<<"Desconstructor"<<endl;
}
};


int main(int argc, char* argv[])
{
std::vector …
[/Quote]


运行结果:

default constructor
Copyconstructor
Copyconstructor
Copyconstructor
Desconstructor
default constructor
default constructor
default constructor
Copyconstructor
Copyconstructor
Copyconstructor
Copyconstructor
Desconstructor
Desconstructor
Desconstructor
Copyconstructor
Copyconstructor
Copyconstructor
Copyconstructor
Copyconstructor
Desconstructor
Desconstructor
Desconstructor
Desconstructor
Copyconstructor


vs2008 编译运行!!
太乙 2008-08-01
  • 打赏
  • 举报
回复

std::vector <A> x(3);
004119BD push 3
004119BF lea ecx,[ebp-24h]
004119C2 call std::vector<A,std::allocator<A> >::vector<A,std::allocator<A> > (41103Ch)
004119C7 mov dword ptr [ebp-4],0
A a1,a2,a3;
004119CE lea ecx,[ebp-2Dh]
004119D1 call A::A (411235h)
004119D6 lea ecx,[ebp-39h]
004119D9 call A::A (411235h)
004119DE lea ecx,[ebp-45h]
004119E1 call A::A (411235h)



explicit vector(size_type _Count)
: _Mybase()
{ // construct from _Count * _Ty()


……
……
_Construct_n(_Count, _Ty());
00411BCF lea ecx,[ebp-0DDh]
00411BD5 call A::A (411235h)
00411BDA push eax
00411BDB mov eax,dword ptr [ebp+8]
00411BDE push eax
00411BDF mov ecx,dword ptr [ebp-14h]
00411BE2 call std::vector<A,std::allocator<A> >::_Construct_n (411316h)
}
wangdeqie 2008-08-01
  • 打赏
  • 举报
回复

//这个完整重贴下!
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A()
{
std::cout <<"default constructor" <<std::endl;
}
A(const A & a)
{
cout<<"Copyconstructor"<<endl;
}
~A()
{
cout<<"Desconstructor"<<endl;
}
};


int main(int argc, char* argv[])
{
std::vector <A> x(3); //以class A为参数类型 需要调通一次默认的构造函数

A a1,a2,a3; //构造三个对象,调用三次构造函数
x.push_back(a1);
x.push_back(a2);
x.push_back(a3);

return 0;
}
wangdeqie 2008-08-01
  • 打赏
  • 举报
回复

//改成这样,你再运行,看下结果,应该能明白了
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A()
{
std::cout <<"default constructor" <<std::endl;
}
A(const A & a)
{
cout<<"Copyconstructor"<<endl;
}
};


int main(int argc, char* argv[])
{
std::vector <A> x(3);

A a1,a2,a3;
x.push_back(a1);
x.push_back(a2);
x.push_back(a3);

return 0;
}
jay的Fans 2008-08-01
  • 打赏
  • 举报
回复
std::vector <A> x(3);//调用一次缺省构造函数,三个对象全是调用了复制构造。
jay的Fans 2008-08-01
  • 打赏
  • 举报
回复
std::vector <A> x(3);//一次
A a1,a2,a3; //三次
richbirdandy 2008-08-01
  • 打赏
  • 举报
回复
std::vector <A> x(3);
这一行调用的是这个构造函数,后两个用的默认值
=======================================
explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );
Repetitive sequence constructor: Initializes the vector with its content set to a repetition, n times, of copies of value
============================
看到这个没const T& value= T(),第一次调用的A的构造函数就在这
晨星 2008-08-01
  • 打赏
  • 举报
回复
调用push_back时有三次拷贝构造,原因跟push_back的内部实现有关。
push_back的参数虽然是引用类型的,但为了避免在将vector中的已有元素push_back进vector时产生bug,它内部还是先拷贝了一份。
这主要是为了避免像下面这样使用时产生bug:

vector<A> v(3);
v.push_back(v[0]);
因为push_back有可能引起内存重新分配和元素拷贝,如果不先把传进来的参数拷贝一份,那么很可能重新分配内存后,原来那个已要失效了。
e_sharp 2008-08-01
  • 打赏
  • 举报
回复
编译器实现的问题,每种编译器可能实现方法不同
加载更多回复(4)

64,642

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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