2016-10-29 5 views
1

Рассмотрим класс Container, который в основном хранит вектор unique_ptr s из Box объектов и может выполнять некоторые вычисления на них.C++ копии объектов с абстрактными указателями класса

class Container 
{ 
    private: 
    std::vector<std::unique_ptr<Box> > boxes_; 
    public: 
    Container(std::vector<std::unique_ptr<Box> > &&boxes): boxes_(std::move(boxes)){} 
    double TotalVolume() { /* Iterate over this->boxes_ and sum */ } 
}; 

Здесь Box это абстрактный класс, который имеет чисто виртуальный метод такой, как double Box::Volume().

Теперь предположим, что я создаю экземпляр контейнера в основной программе, как:

std::vector<std::unique_ptr<Box> > x; 
x.push_back(std::move(std::unique_ptr<Box>(new SquareBox(1.0))); 
x.push_back(std::move(std::unique_ptr<Box>(new RectangularBox(1.0, 2.0, 3.0))); 
Container c(x); 

Как сделать копии c? Мне нужна функция, которая делает копии базового объекта Box в boxes_, но я думаю, что это сложно сделать с базовыми классами?

+0

В любом случае, почему бы вам не использовать std :: vector ? – Danh

+0

Спасибо: C'tor изменился. Что касается не использования 'vector ', 'Container', это, по сути, производный класс некоторого базового класса, который имеет виртуальный метод« TotalVolume ». Моя первоначальная проблема заключается не в коробках и контейнерах, а в каком-то сложном проекте, который я пытаюсь расширить. – Salmonstrikes

ответ

2

Один из способов сделать ваши копии - иметь виртуальный метод «Копировать» в базовом классе. Этот метод создаст копию текущего объекта и вернет ему (уникальный) указатель на него. Если в классе есть какие-либо содержащиеся указатели, им также нужны новые копии (глубокая копия).

Другие подходы существуют. Например, вы можете протестировать каждый объект в векторе, чтобы определить его тип (используя dynamic_cast), но это уродливое, неэффективное и очень подверженное ошибкам.

+0

Это действительно хорошо работает для моей ситуации. Есть ли название для этого шаблона проектирования (метод копирования с 'unique_ptr')? – Salmonstrikes

+1

@Salmonstrikes: общее название - это функция ** clone **. Один из старых гуру назвал его ** виртуальным конструктором **, но в то время как этот термин находится в FAQ по ISO C++ (или, по крайней мере, был в исходных FAQ на C++), это очень редко, если вообще когда-либо используется. Существуют даже опросные листы, предназначенные для проверки вашего знания на С ++, который спрашивает, почему на C++ не может быть виртуального конструктора, тем самым раскрывая как недостаток знаний авторов (который когда-то был термином, используемым хорошо читаемыми людьми), так и авторами «отсутствие способности рассуждать (почти все может быть придано значению при разработке языка). –