2016-10-06 2 views
0

Предположим, у меня есть класс, как следующее:глубокая копия и динамическое приведение unique_ptr

class A { virtual ~A(); ... } 
class B : public A { ... } 
class C : public A { ... } 

У меня также есть вектор unique_ptr который объявлен следующим образом:

std::vector<std::unique_ptr<A>> vec; 

Предположим, VEC заполняемый с unique_ptr к объектам производного класса. Что делать, если я хочу получить глубокую копию любого из векторных элементов, либо b, либо c, и указать на него базовый класс unique_ptr? Первоначально я делал такие вещи, как

std::unique_ptr<A> tmp = std::make_unique<A>(*b); 

Я не думаю, что это правильно. Может кто-то помочь мне с этим?

+2

Это действительно не имеет никакого отношения к 'unique_ptr'. 'A * tmp = new A (* b);' будет более правильным. –

+0

@Nicol Bolas Я хочу использовать unique_ptr, поскольку я не хочу напрямую использовать исходные указатели. – ascetic652

+1

Да, я понимаю. Но причина, по которой вы опубликовали неправильный, не имеет ничего общего с тем фактом, что вы используете 'unique_ptr'. Это не проблема с 'unique_ptr' или' make_unique' или что-то в этом роде. –

ответ

2

Одно из возможных решений состоит в объявить метод виртуального клонирования в базовом классе и переопределить его для каждого подкласса:

class A { 
    virtual ~A() {} 
    virtual std::unique_ptr<A> clone() const = 0; 
} 
class B : public A { 
    std::unique_ptr<A> clone() const override { 
     return std::unique_ptr<A>(new B(*this)); 
    } 
}; 

Редактировать:

Пример использования:

void f(const A& original) { 
    std::unique_ptr<A> copy = original.clone(); 
    // Here, copy points to an instance of class B. 
} 
+0

Должен ли метод клонирования быть const? Если да, то 'const std :: unique_ptr tmp = b.clone()' правильный способ использования этого метода? @ André Sassi – ascetic652

+0

@ ascetic652, он не * должен * быть 'const', но имеет смысл, что клонирование объекта не изменяет оригинальное, не так ли? Тип возвращаемого значения по-прежнему является неконстантным 'unique_ptr' для неконстантного' A' (поскольку он возвращает клонированный, а не оригинал), поэтому нет никаких дополнительных требований для использования 'clone'. –

+0

Можно ли использовать 'return std :: make_unique (* this)'? @ André Sassi – ascetic652

Смежные вопросы