deep copy of object which hold references to other objects
I have a "sum" class which holds two references to existing ints (say). I want to create a "copy" method which deep copies the ints. I thought I would never have to manually delete
objects in my code, thanks to smart pointers, but I had to in this solution. Moreover, it is too complicated for a so trivial task (which I need to repeat for several classes). Is there a more straightforward solut开发者_如何学Goion?
Note: I don't want to add a bool member (flag) to each objects to determine if the ints must be deleted (in my case, it's not a better overhead than the std::set
check overhead in the destructor)
#include <set>
struct sum {
const int &a, &b;
static std::set<const int*> allocated_ints;
sum(const int& a, const int&b): a(a), b(b) {}
sum copy() const {
sum res(*new const int(a), *new const int(b));
allocated_ints.insert(&res.a);
allocated_ints.insert(&res.b);
return res;
}
~sum() {
if (allocated_ints.count(&this->a)) {
delete &this->a;
delete &this->b;
allocated_ints.erase(&this->a);
allocated_ints.erase(&this->b);
}
}
};
std::set<const int*> sum::allocated_ints;
What's the point of a "deep" copy of constants? The constants are going to have the same value no matter what! So just copy (i.e. alias) the const-references:
struct Foo
{
const int & n;
Foo(const int & m) : n(m) { }
Foo(const Foo & rhs) : n(rhs.n) { }
Foo copy() const { Foo f(*this); /* ... */ return f; }
// ...
};
If you're worried about dangling references when returning a copy from a function with a reference to a local variable, then don't make the class have const references, but copies. That way you naturally give your class the copy semantics that you seem to be after anyway.
If you were thinking that you could make a hybrid which is either non-owning or becomes owning depending on how you use it, then I'd say that's bad design that you should avoid. Decide whether your class has ownership over the data or not and then roll with it.
I think you're mixing-up two incompatible concepts.
If you initialize by reference you should refer to existing object whose lifetime is already defined and should be longer than your objects.
If you want to create a copy of your object, since it refers to something, your copy will also refer to that something.
If you want to own yourself dynamic supplied objects, you should use pointers for that, and acquire them as pointers (and delete them on destruction). A copy can then deep-create copies of the pointed objects (or can share them using reference counting or shared_ptr).
You are -in fact- making up a mixing of the two things, resulting in possible problems: think to:
int main()
{
const int x=5; //whatever it is
Foo foo(x);
// ...
} //danger here! ~Foo() will delete x
The references are not deep copied, because they point to an object. Therefore, your code fixed should look like this :
struct sum {
const int &a, &b;
sum(const int& a, const int&b): a(a), b(b) {}
sum copy() const {
sum res(a,b);
return res;
}
~sum() {
}
};
精彩评论