Sign in to follow this  
Kyall

Templating safe copy of classes, pointers & arrays

Recommended Posts

Kyall    287
I want to create a template class that I can use to set an instance as a copy only. I know I can do this:

class A;

class UsesA
{
public:
UsesA( const UsesA& other ) { mya = other.mya; }
private:
A mya;
};

Where A has it's copy constructor handled so every thing is nice and safe.
what I want to do is this:

class UsesA
{

private:
safe_copy<A> mya;
};

Basically I want to be assured that the memory from one thing to another is copied correctly when I want to copy it, and not store it as a smart pointer. An I figure I should do up a few templates to handle this, and use them where necessary, for example: the following

struct SomeStruct { int x; }
class SomeClass
{
protected:
int x,y,z;
safe_array<int> _pAnIntArray;
};

class B
{
protected:
safe_pointer<SomeStruct> _pSomeStruct;
safe_class<SomeClass> _pSomeClass;
safe_array<int> _pIntArray;
};

Where the complex version of this is SomeClass, which also implements the templates where necessary, so that copy is handled properly. So my questions are:

1. If i use this sort of thing, but do not implement a copy constructor in the classes that use them, will the fact that they are being used ensure that the copy constructors coming from the template will be called, and everything will be fine. If this is a no, I don't mind so much, it's easier to write safe_array<x> x = y, then it is to write copy code everywhere it's needed.
2. What are some use cases in which you think these templates could be useful, so what scope of implementation do I pursue with these copy templates.
3. safe_class seems to me to be a problem... Because to actually use it the class must have a copy constructor by default. What's the best way I can create a template to reduce the programming for copying classes safely.

Reading the c11 description, they've introduced some form of copy/reference safety as a default, what I want is to have it in templates I can use.

Share this post


Link to post
Share on other sites
the_edd    2109
[quote name='Kyall' timestamp='1331707955' post='4921893']
I want to create a template class that I can use to set an instance as a copy only.
[/quote]

[quote]
Basically I want to be assured that the memory from one thing to another is copied correctly when I want to copy it, and not store it as a smart pointer.
[/quote]

These requirements aren't particularly clear. Are you saying you want a generic way to perform what's often called a [i]deep copy[/i]? What does "copied correctly" actually mean in a generic context? Surely the assessment has to be made on a case-by-case basis (at which point you might as well not bother with a generic wrapper)?

If my understanding of your request is correct, my first question is: why do you want to do this? Given that I've never heard anyone ask this question before (in C++), it suggests there might be a better way of achieving your higher-order goal.

Share this post


Link to post
Share on other sites
Kyall    287
It's basically as you describe it, a deep copy templated class. And it is a rare case thing. But the idea behind it is that when I need to deep copy, some elements of human error are removed, so that I've less bugs to fear, because I'm reusing some nice safe and tested code. And the deep copy is really only for design cases where the state of another object needs to be copied into a new object that has it's own memory so that the new instance can be modified safely.

Not all of the members of the new instance need to be copied though, some times there might be shared pointers in there. But the general idea is that any member a class has, will automagically have the correct copy/assignment code, without having to implement a copy constructor and assignment operator; not because I hate them, I actually quite like writing copy constructors and assignment operators, but so that I can reduce the amount of code, therefore decreasing bugs.

Basically to be used pretty rarely and to improve stability.

Share this post


Link to post
Share on other sites
ApochPiQ    23003
How does this magic system know what members are to be deep copied and how? What prevents you from accidentally not marking a member for deep copy, thereby creating the same problem as mucking up a copy constructor/assignment operator? And what exactly makes you think that this will improve the situation, given that anyone who has never seen this code setup before will be very confused? (i.e. it's [i]more[/i] likely that someone will screw up your system, because it isn't idiomatic.)

Share this post


Link to post
Share on other sites
the_edd    2109
There's no way of doing this without a lot of manual work for each type, as C++ doesn't have the kind of introspection capabilities required. It may be possible to detect if an object has an operator->, in which case you might assume that you should copy the result of applying operator*, but that's far from fool-proof.

In some cases, doing a deep copy would actually be counter productive e.g. deep-copying a shared_ptr<const Image> would needlessly copy (probably) immutable raster data. In other cases a deep copy would be outright wrong e.g. deep copying the object at the end of a pointer, when that pointer is acting as an identifier in some larger pooling system.

Trying to come up with some automatic deep-copy mechanism seems like it's inherently [i]less safe[/i] than just thinking about what you're doing each time.

Instead, I'd suggest that you give each class clear copying semantics, by making behave as a value-type, or by giving it reference-counted innards, or by making it un-copyable. In that way, copying, where allowed, will always be safe.

Share this post


Link to post
Share on other sites
Red Ant    471
On top of what's been said above, your copy constructor doesn't really "initialize" per se; it assigns. Instead of this

[code]
UsesA( const UsesA& other ) { mya = other.mya; }
[/code]

what you really want to do is this

[code]
UsesA( const UsesA& other ) : mya( other.mya ) {}
[/code]

When writing constructors, it's generally advisable to prefer initialization lists over assignment.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this