Templating safe copy of classes, pointers & arrays

Started by
4 comments, last by Red Ant 12 years, 1 month ago
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.
I say Code! You say Build! Code! Build! Code! Build! Can I get a woop-woop? Woop! Woop!
Advertisement

I want to create a template class that I can use to set an instance as a copy only.



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 deep copy? 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.
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.
I say Code! You say Build! Code! Build! Code! Build! Can I get a woop-woop? Woop! Woop!
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 more likely that someone will screw up your system, because it isn't idiomatic.)

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

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 less safe 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.
On top of what's been said above, your copy constructor doesn't really "initialize" per se; it assigns. Instead of this


UsesA( const UsesA& other ) { mya = other.mya; }


what you really want to do is this


UsesA( const UsesA& other ) : mya( other.mya ) {}


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

This topic is closed to new replies.

Advertisement