2009-09-28 4 views
10

Предположит, я следующий (упрощенный случай):конструктор копирования: глубокое копирование абстрактного класса

class Color; 

class IColor 
{ 
public: 
    virtual Color getValue(const float u, const float v) const = 0; 
}; 

class Color : public IColor 
{ 
public: 
    float r,g,b; 
    Color(float ar, float ag, float ab) : r(ar), g(ag), b(ab) {} 
    Color getValue(const float u, const float v) const 
    { 
     return Color(r, g, b) 
    } 
} 

class Material 
{ 
private: 
    IColor* _color; 
public: 
    Material(); 
    Material(const Material& m); 
} 

Теперь, есть ли способ для меня, чтобы сделать глубокую копию абстрактного обеспечивающего лучшего соотношения в копии конструктора Материал? То есть, я хочу, чтобы значения любого m._color могли быть (цвет, текстура) скопированы, а не только указатель на IColor.

ответ

7

К вашему интерфейсу можно добавить функцию clone().

1

Вам придется добавить этот код самостоятельно к конструктору копии материалов. Затем код, чтобы освободить выделенный IColor в деструкторе.

Вы также захотите добавить виртуальный деструктор в IColor.

Единственный способ сделать глубокую копию автоматически - это сохранить цвет непосредственно, а не указатель на IColor.

+0

Почему сохранение указателя на IColor отключит глубокую копию? –

+0

Поскольку по умолчанию он просто копирует адрес указателя в адрес скопированного указателя. Он не будет копировать то, на что указывает, а затем перенастроить указатель. У Luke есть лучшее предложение в создании функции clone(), вызванной из конструктора копирования. –

0

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

+0

Но вы не знаете, является ли это цветом или текстурой, как вы можете динамически? – Barth

+0

Если объект не имеет цвета цвета, тогда dynamic_cast (_color) вернет значение null. (Dynamic cast/rtti может определить, что такое фактический тип, если класс имеет хотя бы один виртуальный метод). Итак, что вы можете сделать, это проверить возможности. Это не забавно и почти всегда хуже, чем использование метода clone(), но есть редкие ситуации, когда вам нужно сделать что-то подобное. –

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