2009-09-28 15 views
10

Giả sử tôi đã như sau (đơn giản trường hợp):Sao chép constructor: sâu sao chép một lớp trừu tượng

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); 
} 

Bây giờ, là có cách nào cho tôi để làm một bản sao sâu của iColor trừu tượng trong các nhà xây dựng bản sao của Vật chất? Đó là, tôi muốn các giá trị của bất cứ điều gì m._color có thể là (một màu, một Texture) để được sao chép, không chỉ là con trỏ đến IColor.

Trả lời

7

Bạn có thể thêm một hàm nhân bản() vào giao diện của mình.

1

Bạn sẽ phải tự thêm mã đó vào trình tạo bản sao Material. Sau đó, mã để giải phóng IColor được cấp phát trong trình phá hủy của bạn.

Bạn cũng sẽ muốn thêm trình phá hủy ảo vào IColor.

Cách duy nhất để thực hiện sao chép sâu tự động là lưu trữ màu trực tiếp thay vì trỏ đến một IColor.

+0

Tại sao lưu con trỏ trên IColor sẽ vô hiệu hóa bản sao sâu? –

+0

Bởi vì theo mặc định nó sẽ chỉ sao chép địa chỉ con trỏ vào địa chỉ con trỏ được sao chép. Nó sẽ không sao chép những gì đang được trỏ đến và sau đó điều chỉnh lại con trỏ. Luke có gợi ý tốt nhất trong việc tạo ra một hàm clone() được gọi từ hàm tạo bản sao. –

0

Thêm một phương pháp clone() để màu có lẽ là tốt nhất, nhưng nếu bạn không có tùy chọn đó, một giải pháp khác sẽ được sử dụng dynamic_cast để cast iColor * Color *. Sau đó, bạn có thể gọi hàm tạo bản sao Màu.

+0

Nhưng bạn không biết nếu nó là một màu hoặc một kết cấu, làm thế nào bạn có thể dynamic_cast sau đó? – Barth

+0

Nếu đối tượng không thuộc loại màu thì dynamic_cast (_color) sẽ trả về giá trị rỗng. (Dynamic cast/rtti có thể phát hiện loại thực tế nào miễn là lớp có ít nhất một phương thức ảo). Vì vậy, những gì bạn có thể làm là kiểm tra khả năng. Đây không phải là niềm vui, và gần như luôn luôn tồi tệ hơn sau đó sử dụng một phương pháp clone(), nhưng có những tình huống hiếm hoi mà bạn phải làm một cái gì đó như thế này. –