Re: need help creating a two dimensional vector that holds pointers
of a user defined type
On Apr 8, 5:46 am, dwightarmyofchampi...@hotmail.com wrote:
[...]
for (std::vector<ABC*>::iterator it = vec.begin();
it != vec.end();
it++)
{
delete *it; *it = 0;
I can understand deleting (since you allocated it using
'new'), but why do you care to set it to 0? The vector is
going to be destroyed right after the destructor's body
finishes...
I never really understood the rule about setting pointers to
zero, it was always something my professor told me to do "to
be on the safe side." So I just ended up setting all my
pointers to zero after delete statements without really giving
much thought as to what it did.
I'd suggest changing professors. There are only two cases where
setting the pointer to null makes sense: the first is if you're
sure that it's the only pointer to the object, and you're going
to check for null later. The second is when there is a risk
that the pointer may be copied or otherwise read later. The
second actually applies here (formally)---the problem is that
theoretically, at least, the old pointer value could be read in
the *it sub-expression of the assignment, before it has been set
to null, so this isn't sufficient.
In practice, the second reason is extremely theoretical to begin
with; there are very, very few machines where just reading an
invalid pointer value can cause problems, and then, only if it
has been invalidated at the OS level. (One of the very few
machines is the Intel 80x86, of course. But in fact, the more
usual OS's don't support segmented pointers, so the problem
doesn't exist, and even if the OS supported segmented pointers,
there are very good reasons for the compiler not to generate the
instructions which would cause problems.)
So, when do need to set the opointer equal to zero and when is
it unnecessary?
Basically, it's only necessary if you're going to check for
null, somewhere. And it can only work, really, if there are no
other pointers to the object.
It's a 'vector<ABC*>', of course! So, you need to push an instance of
that object onto your 'vec' before entering the inner loop:
for (int i = 0; i < 7; ++i)
{
vec.push_back(vector<ABC*>()); // now you have i-th element
for (int j = 0; j < 5; ++j)
vec[i].push_back(new ABC(j));
}
OK, now here is something I am totally clueless about:
vector<ABC*>()
What is with the two parentheses at the end?
Technically, it's what the standard calls an "explicit type
conversion (functional notation)". Practically, it creates a
temporary object of type vector<ABC*>, using default
initialization to initialize it.
Does that mean that it's an empty vector?
Yes, since that's what vector's default constructor does.
Is there anything we could put in those parentheses if we
wanted to?
Anything that's acceptable as arguments to a constructor of
vector. Victor could also have written:
for ( int i = 0 ; i < 7 ; ++ i ) {
vec.push_back( vector< ABC* >( 5 ) ) ;
for ( int j = 0 ; j < 5 ; ++ j ) {
vec[ i ][ j ] = new ABC( j ) ;
}
}
For that matter, in the constructor initializer list, you could
have written:
: vec( 7, vector< ABC* >( 5 ) )
And then just used:
for ( int i = 0 ; i < 7 ; ++ i ) {
for ( int j = 0 ; j < 7 ; ++ j ) {
vec[ i ][ j ] = new ABC( j ) ;
}
}
Depending on the implementation, this might even be marginally
faster (although if you're new'ing each element, I can't imagine
that the difference would be measurable). But the push_back
idiom that Victor used is the consacrated idiom.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34