Reputation: 4539
I have the following situation:
I need to create a deep (!) copy of a variable from type A
. This variable contains a vector of type B
. Class B
is not copyable, because it contains a std::unordered_map
whos value is a unique_ptr
(which is not copyable). I would like to avoid making B
copyable via a copy constructor or copy assignment operator.
One problem is that the type of the unique_ptr
is just the base type. The actual objects are derived from C
and contain different members and have different constructors.
class A{
public:
A(const A&); // how should I implement this?
A& operator=(const A&); // how should I implement this?
private:
vector<B> vectorOfB;
}
class B{
private:
std::unordered_map<std::string, std::unique_ptr<C> mapOfDerivedTypesOfC;
}
class C{}
class C_1: public C{
public:
C_1(double x)
}
class C_2: public C{
public:
C_2(double y, double z)
}
Background: The purpose of class A is to read a lot of large text files with data and create many objects. Afterwards I have to run monte-carlo simulations with this objects. For every simulation I need a fresh copy of A. I do not want to read in all the text files every time because it is time consuming. Therefore it is necessary to make a deep copy of A. During one simulation I want to avoid copying B because it makes no sence that this object should ever be copied. I think using a sharded_ptr does not help because I need a deep copy and the simulations run in parallel using openMP.
Edit: I think the overall question is how should I copy the unordered_map
Upvotes: 1
Views: 945
Reputation: 17415
I think the technique is known as "virtual copy constructor":
// in baseclass
public:
unique_ptr<Base> clone() const
{
unique_ptr<Base> other(this->do_clone());
assert(typeid(*this) == typeid(*other));
return other;
}
private:
virtual Base* do_clone() const = 0;
// in derived class
private:
virtual Derived* do_clone() const
{
return new Derived(*this);
}
The idea is that a type eventually has info how to clone instances of itself, so you delegate cloning to it via a virtual function. The assertion makes sure that the derived class correctly implements/overrides the baseclass implementation.
Upvotes: 2
Reputation: 1136
Long story short, you would need to write a virtual function in C
for each inheriting class to override. Something like
virtual std::unique_ptr<C> anotherOnePlease() = 0;
Then you can use this function on each C *
, and create a new map. Kind of sucks, but at least you can write a somewhat simple function for copying the map if you implement this function for each derived C
.
Upvotes: 1