简体   繁体   中英

deep copy of objects containing unordered_map of unique_ptr

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

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM