Inheritance, vectors and copy

N

Nudge

I am slightly confused, so please keep that in mind if I make
only little sense.

Assume I have a base class:

class Base { ... };

and two derived classes:

class Int : public Base { ... int foo; };
class Double : public Base { ... double bar; };

Assume I want to keep a vector of Int's OR Double's.

I could write either
std::vector<Base *> v1;
or
std::vector<Base &> v2;

So far, so good?

I'm probably missing something fundamental: is there a real
difference between v1 and v2? Will v2 work with virtual functions?

I'll allocate several Int's and Double's on the heap with new
and store them in v2, for example.

Now I want to copy v2 into v3. If I just write v3 = v2, I'll end up with
the same references in v2 and v3, right? What I want is to copy every
object in the vector and store the reference to the copy in v3. That
way, if I modify an object in v3, v2 won't be affected.

One way I see is to overload operator=

typedef std::vector<Base &> MyVec;

MyVec &operator=(MyVec &)
{
for every element in MyVec, call a virtual self-copy method;
}

Is that acceptable? Is there a better way?
 
L

Leor Zolman

I am slightly confused, so please keep that in mind if I make
only little sense.

Assume I have a base class:

class Base { ... };

and two derived classes:

class Int : public Base { ... int foo; };
class Double : public Base { ... double bar; };

Very clear.
Assume I want to keep a vector of Int's OR Double's.

I could write either
std::vector<Base *> v1;
Okay

or
std::vector<Base &> v2;

Not okay. References do not meet the requirements for elements of a
container; they're neither copyable nor assignable. Internally, STL
containers have to assign and copy their elements, and you just can't do
that with references. You'd never even be able to get them into a container
in the first place.
So far, so good?

Only the pointer version.
I'm probably missing something fundamental: is there a real
difference between v1 and v2? Will v2 work with virtual functions?

Let's forget about references in containers. For the rest of this
discussion, let's assume v2 is like v3: a container of Base *'s.
I'll allocate several Int's and Double's on the heap with new
and store them in v2, for example.
Okay.


Now I want to copy v2 into v3. If I just write v3 = v2, I'll end up with
the same references in v2 and v3, right? What I want is to copy every
object in the vector and store the reference to the copy in v3. That
way, if I modify an object in v3, v2 won't be affected.

If v3 is also a container of Base *'s, then yes, just saying
v3 = v2;
will copy the pointers and do nothing else. To replicate all the data, you
can just do it in a loop (untested code):

std::vector<Base *> v3;
for (int i = 0; i < v2.size(); ++i)
v3.push_back( v2->clone());

assuming you've set up a cloning ("virtual copy constructor") mechanism for
objects in the Base hierarchy.

One way I see is to overload operator=

typedef std::vector<Base &> MyVec;

MyVec &operator=(MyVec &)
{
for every element in MyVec, call a virtual self-copy method;
}

Is that acceptable? Is there a better way?

See above.
-leor
 
V

Victor Bazarov

Nudge said:
I am slightly confused, so please keep that in mind if I make
only little sense.

Assume I have a base class:

class Base { ... };

and two derived classes:

class Int : public Base { ... int foo; };
class Double : public Base { ... double bar; };

Assume I want to keep a vector of Int's OR Double's.

I could write either
std::vector<Base *> v1;
or
std::vector<Base &> v2;

So far, so good?

No, you cannot write

std::vector<Base &> v2;

References cannot be stored in a vector.
I'm probably missing something fundamental: is there a real
difference between v1 and v2? Will v2 work with virtual functions?

No, since 'v2' cannot exist, it will not work with virtual functions.
I'll allocate several Int's and Double's on the heap with new
and store them in v2, for example.

No, you cannot do that. Nobody can do that.
Now I want to copy v2 into v3. If I just write v3 = v2, I'll end up with
the same references in v2 and v3, right?

Nope, it cannot be done.
What I want is to copy every
object in the vector and store the reference to the copy in v3. That
way, if I modify an object in v3, v2 won't be affected.

One way I see is to overload operator=

typedef std::vector<Base &> MyVec;

MyVec &operator=(MyVec &)
{
for every element in MyVec, call a virtual self-copy method;
}

Is that acceptable? Is there a better way?

This is not acceptable. Your only option is to go with v1 (storing
the pointers to Base) and perform your own copying with simulated
"deep" copy of objects.

The problem is that (a) you cannot define the operator= that is not
a member of the class for which you try to define it and (b) the
existing operator= in 'std::vector' will not do the job correctly.

You need to roll out your own copy function.

Victor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,190
Latest member
ClayE7480

Latest Threads

Top