copy constructor.
AliR.
First thing: it is odd, but I could not read AliR's post
?_?
I only came into it thanks to Joe's quoting below.
"Joseph M. Newcomer" <newcomer@flounder.com> ha scritto
nel messaggio
news:s4q4t498s92d9v26d4tgr48trdmqfb2p8k@4ax.com...
This is one of the reasons that vectors of pointers are
often a better choice than vectors
of objects, because the pointers can be trivially
copied.
I agree, if the object is heavy to copy (but for
something like a vector of complex numbers, considering
that each complex instance is a pair of double's, I think
that vector<complex<double> > should be just fine).
For objects heavy to copy, I would consider vector<
shared_ptr< X > > as a good solution, thanks to automatic
reference counting built in shared_ptr smart pointer.
Commenting on AliR's post:
On Tue, 31 Mar 2009 10:32:00 -0500, "AliR \(VC++ MVP\)"
<AliR@online.nospam> wrote:
It is not a bug.
say you have
class CMyObject
{
....
};
vector<CMyObject> MyVector;
MyVector.push_back(x); //this will call the copy
constructor twice
MyVector.push_back(x); //this will call it 3 times.
// and so on and so forth.
It is just how vector allocates and moves things around
when new items are
added. When it is empty and an item is added, it first
allocates the space
for it which calls the copy constructor of the template
item, then it
actually copies it in there, which again calls the copy
constructor.
I think that in case #1, only one copy constructor is
called, because the push_back() method of class vector
takes an input parameter which is a *reference* to
template type T, e.g.
void push_back( const T & val );
so I think that only one copy ctor is required for the
first call.
Instead, for next calls, the copy ctors are required when
the vector size exceeds its capacity.
A small test program shows it clearly (note that when
vector capacity is big enough - after the first few
reallocations - only one copy ctor is invoked for each
push_back()):
<output>
...
...
push_back(MyClass(20));
MyClass ctor (X = 20)
MyClass copy ctor (X = 20)
MyClass dtor (X = 20)
----
push_back(MyClass(21));
MyClass ctor (X = 21)
MyClass copy ctor (X = 21)
MyClass dtor (X = 21)
----
push_back(MyClass(22));
MyClass ctor (X = 22)
MyClass copy ctor (X = 22)
MyClass dtor (X = 22)
----
push_back(MyClass(23));
MyClass ctor (X = 23)
MyClass copy ctor (X = 23)
MyClass dtor (X = 23)
----
</output>
<code>
#include <vector>
#include <iostream>
using std::cout;
using std::endl;
class MyClass
{
public:
MyClass()
: X(0)
{
cout << "MyClass default ctor." << endl;
}
explicit MyClass(int x )
: X(x)
{
cout << "MyClass ctor (X = " << X << ")" << endl;
}
MyClass( const MyClass & src )
: X(src.X)
{
cout << "MyClass copy ctor (X = " << X << ")" <<
endl;
}
~MyClass()
{
cout << "MyClass dtor (X = " << X << ")" << endl;
}
MyClass & operator=(const MyClass & src)
{
cout << "MyClass operator=" << endl;
if (&src != this)
{
X = src.X;
}
return *this;
}
int X;
};
void Test()
{
int count = 24;
std::vector< MyClass > myClasses;
for (int i = 0; i < count; i++)
{
cout << "push_back(MyClass(" << i << "));" <<
endl;
myClasses.push_back( MyClass(i) );
cout << "----" << endl;
}
}
int main()
{
Test();
return 0;
}
</code>
Giovanni