What to do when you want a Shallow Copy?

C

coredumperror

Hi all you C++ gurus out there,
I've got what may be an unusual question. What's the best way to
get a shallow copy of a class that you've programmed to prevent
accidental shallow copying? I've got an operator= that does deep copy,
and a copy constructor that does deep copy... is there any way for me
to get a shallow copy without writing a function that maually copies
each member datum into an out parameter? I'd love to be able to just
return *this, but that'd invoke my deep copy constructor, which I don't
want. Any suggestions?
 
P

Phlip

coredumperror said:
I've got what may be an unusual question. What's the best way to
get a shallow copy of a class that you've programmed to prevent
accidental shallow copying? I've got an operator= that does deep copy,
and a copy constructor that does deep copy... is there any way for me
to get a shallow copy without writing a function that maually copies
each member datum into an out parameter?

Whats wrong with Object b = a.shallowCopy();?

What does shallow copy mean to you?

Why would writing such a function be hard?

The ultimate answer to your question is "C++ Reflection", which is an
absurdly hairy topic, and much harder than just writing

Or do you have too many classes that need shallow copies? So then why are
there too many classes?
 
V

Victor Bazarov

I've got what may be an unusual question. What's the best way to
get a shallow copy of a class that you've programmed to prevent
accidental shallow copying? I've got an operator= that does deep
copy, and a copy constructor that does deep copy... is there any way
for me to get a shallow copy without writing a function that maually
copies each member datum into an out parameter?

Most likely, no. Copying through construction and copying through
assignment are two copying that exist. You can always memcpy, but
it usually is a BAD IDEA(tm) if your class has virtual functions, for
example. Besides, the language give no guarantees if your class is
not a POD.
I'd love to be able
to just return *this, but that'd invoke my deep copy constructor,
which I don't want. Any suggestions?

How would you use it, BTW?

V
 
C

coredumperror

Most likely, no. Copying through construction and copying through
assignment are two copying that exist. You can always memcpy, but
it usually is a BAD IDEA(tm) if your class has virtual functions, for
example. Besides, the language give no guarantees if your class is
not a POD.

What's a POD?
How would you use it, BTW?

I've only got one class so far, which is a really simple RawImage
class. It contains the pointer to an array of bytes for each pixel,
and ints for the width, the height, the color channels, and the total
size (width*height*chans). I'd like to be able to copy the pointer
value and the ints for width, etc in a more concise way than manually
assigning them into an out parameter. Maybe I'm just trying to be too
clever for my own good?

-Robert
 
R

Rolf Magnus

What's a POD?

Plain Old Data. Basically a built-in type or a class/struct that has only
public members, no virtual functions, no base classes, no user-defined
constructors or destructor and only member variables that are themselves
POD.
I've only got one class so far, which is a really simple RawImage
class. It contains the pointer to an array of bytes for each pixel,
and ints for the width, the height, the color channels, and the total
size (width*height*chans). I'd like to be able to copy the pointer
value and the ints for width, etc in a more concise way than manually
assigning them into an out parameter. Maybe I'm just trying to be too
clever for my own good?

I'd do it the other way round. Let the copy constructor and assignment
operator make a shallow copy and write a copy() member function that makes
a deep copy. But that means that the data has to be reference counted.
 
C

coredumperror

Rolf said:
Plain Old Data. Basically a built-in type or a class/struct that has only
public members, no virtual functions, no base classes, no user-defined
constructors or destructor and only member variables that are themselves
POD.

Ah, I didn't know that acronym, but I understood the concept. :)
I'd do it the other way round. Let the copy constructor and assignment
operator make a shallow copy and write a copy() member function that makes
a deep copy. But that means that the data has to be reference counted.

I really don't like the idea of making shallow destructors and copy
constructors...my C++ professor at college drilled that into my head
pretty hard. I guess I'll just stick with my
RawImage.ShallowCopy(RawImage *out) function.
http://www.parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.7

Also, you should read the rest of the FAQ while you're there. There's
lots of good stuff in it.

I've used that FAQ for years, and I love it! I asked my question here
only after looking for the answer there :).
 
P

Phlip

coredumperror said:
I really don't like the idea of making shallow destructors and copy
constructors...my C++ professor at college drilled that into my head
pretty hard.

Did they tell you that some objects should be big and stationary, and that
"value" objects should be small and should copy around? The ultimate
examples here would be simCity, to simulate a city, and std::string, whose
object identity is less important.
I guess I'll just stick with my
RawImage.ShallowCopy(RawImage *out) function.

Why not a return value?

Otherwise, why not a reference?
 
B

benben

I've only got one class so far, which is a really simple RawImage
class. It contains the pointer to an array of bytes for each pixel,
and ints for the width, the height, the color channels, and the total
size (width*height*chans). I'd like to be able to copy the pointer
value and the ints for width, etc in a more concise way than manually
assigning them into an out parameter. Maybe I'm just trying to be too
clever for my own good?

Why not just return a const reference? Like:

const RawImage& f()
{
static RawImage ri;

// blah blah blah

return ri;
}

int main()
{
const RawImage& r = f();
void* p = r.pixels_ptr();
int i = r.width();
// and so on...
}


Ben
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top