Re: Am I misusing std::vector?
Heinz Ozwirk wrote:
"loose AT astron DOT nl" <loose@astron.nl> schrieb im
Newsbeitrag
news:1147252936.701110.275280@j73g2000cwa.googlegroups.com...
I was surprised by the output of the program below. From
what I understand from the C++ STL documentation,
vector<T>::resize(N), will create N *newly constructed*
objects of T. So, I expected *v[0].ip to be equal to 0, and
*v[sz-1].ip equal to -77. However, I discovered, using a few
different compilers (two different versions of gcc, and
icc), that both return -77. It turns out that only *one*
object is being constructed and this one object seems to be
bitwise copied to the other members. See my code below and
try it for yourself. Am I missing something here?
If only one new element is constructed and a bitwise copy
would be used, that would really be a serious bug. But I
doubt that that really happens. But there are other ways to
construct an object than using its default ctor. Elements of
a vector (or any other STL container) must have a valid copy
ctor, and that one could be used by resize.
That is the one required to be used by resize. You can
instantiate a vector on a type without a default constructor,
and call resize on it. (Of course, you cannot in this case use
the default second parameter for resize -- you must provide
explicitly the value to be copied.)
You can simply test that. Just add a copy ctor to your class
and verify that it is called by resize.
struct A
{
A(int i = 0) { ip = new int(i); }
~A() { delete ip; }
int* ip;
};
A class (or struct) that has a non-trivial destructor, should
also have a customized copy ctor and an assignment operator
(Rule of Three).
More of a nit than anything else, but the rule only concerns
classes with non-empty user defined destructors. Had he used
boost::shared_ptr, instead of a raw pointer, and not provided a
destructor, the destructor would not be trivial; similarly, most
of us have a certain number of classes with an empty user
defined destructor -- because the class is meant to be used as a
base class, and the destructor must be virtual.
On the other hand, if you have to do something explicitly in the
destructor, there's a good chance that you're rule of three
would apply. (An obvious exception is when what you have to do
is only notification. Except that I've never found myself in
that situation with a class which supported copy and
assignment.)
If you put instances of that struct in an STL container, it is
your fault if the program doesn't work as expected.
You don't even have to put them in an STL container. The first
copy or assignment will cause problems.
You used the pointer member and didn't supply proper
assignment and copy construction.
--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]