2012-05-14 31 views
5

Tôi có mối quan hệ sau đây của các lớp. Tôi muốn sao chép lớp Derived, nhưng tôi nhận được lỗi "không thể khởi tạo lớp trừu tượng". Làm thế nào tôi có thể sao chép các lớp học có nguồn gốc? Cảm ơn.Nhân bản lớp C++ với các phương pháp ảo thuần túy

class Base { 
public: 
    virtual ~Base() {} 
    virtual Base* clone() const = 0; 
}; 

class Derived: public Base { 
public: 
    virtual void func() = 0; 
    virtual Derived* clone() const { 
     return new Derived(*this); 
    } 
}; 
+0

Điều này sẽ làm gì? Một bản sao bản chất là một hoạt động cấp đối tượng. Nếu không có một vật thể cụ thể, làm thế nào để bạn biết những gì để nhân bản? – Joe

Trả lời

2

Chỉ có thể sắp xếp lớp bê tông. Func không được thuần khiết.

4

Bạn không thể nhanh chóng một lớp học trong đó có một hàm ảo thuần tuý như thế này:

virtual void yourFunction() = 0 

Tạo một lớp con hoặc loại bỏ nó.

+0

hoặc cung cấp triển khai – obmarg

6

Chỉ có thể khởi tạo các lớp cụ thể. Bạn phải thiết kế lại giao diện của Derived để làm nhân bản. Ban đầu, xóa void ảo func() = 0; Sau đó, bạn sẽ có thể viết mã này:

class Base { 
public: 
    virtual ~Base() {} 
    virtual Base* clone() const = 0; 
}; 

class Derived: public Base { 
public: 
    virtual Derived* clone() const { 
     return new Derived(*this); 
    } 
}; 

Một giải pháp khác là giữ hàm ảo thuần tuý tại chỗ và thêm một lớp bê tông:

class Base { 
public: 
    virtual ~Base() {} 
    virtual Base* clone() const = 0; 
}; 

class Derived: public Base { 
public: 
    virtual void func() = 0; 
}; 

class Derived2: public Derived { 
public: 
    virtual void func() {}; 
    virtual Derived2* clone() const { 
     return new Derived2(*this); 
    } 
}; 
0

tôi có thể nói điều gì đó ngu ngốc ở đây, nhưng Tôi nghĩ rằng phương pháp nhân bản trong lớp dẫn xuất vẫn nên trả về một con trỏ đến lớp cơ sở. Có lẽ nó vẫn biên dịch tốt, nhưng theo như khả năng bảo trì của mã có liên quan, tôi nghĩ tốt hơn là sử dụng phương thức sao chép chỉ để trả về con trỏ tới lớp cơ sở. Xét cho cùng, nếu lớp được thừa kế của bạn phải sao chép vào một con trỏ đến một lớp học có nguồn gốc, bạn có thể cũng chỉ làm

Derived original; 
Derived* copy = new Derived(original) 

Tất nhiên, bạn cần phải thực hiện các constructor sao chép, nhưng điều đó thường cần được thực hiện anyway (ngoại trừ trường hợp cực đoan).

Các vấn đề liên quan