Tôi có một mô hình thực hiện tổng hợp, được sử dụng cho các thành phần GUI:Khả năng trộn Composite Pattern và mẫu hoa văn một cách tò mò định kỳ
class CObject {
private:
CObject * m_pParent;
CObjectContainer * m_pChildren;
void private_foo() {
this->foo();
//Calls private_foo for each child in container.
m_pChildren->foo();
}
public:
virtual void foo() {
//empty for base class
}
virtual CObject * duplicate() {
//Do duplication code
return new CObject(*this);
}
virtual CObject * detach() {
//Remove this object (along with it's children)
//from current tree.
m_pParent->RemoveChild(this);
m_pParent = nullptr;
return this;
}
}
class CSpecificObject : public CObject {
public:
virtual void foo() {
//Specific code for this class
}
virtual CSpecificObject * duplicate() {
//Overload, but the code only calls diferent constructor
return new CSpecificObject(*this);
}
virtual CSpecificObject * detach() {
//Note the code is identical.
m_pParent->RemoveChild(this);
m_pParent = nullptr;
return this;
}
}
Đáng tiếc là số lượng các lớp học di truyền tăng lên nhanh chóng và mã trùng lặp (trong ví dụ đưa ra chỉ các Phương thức detach() đang khiến tôi đau đầu.
Có cách nào để thực hiện sạch các phương thức tách rời(), giữ kiểu trả về giống với đối tượng mà trên đó nó được gọi không?
Tôi đã suy nghĩ về CRTP, nhưng tôi không thể nghĩ ra một cách để giữ cho đa hình năng động cùng với thời gian biên dịch đa hình:
template <Child>
class CObject {
private:
...
Child * detach() {
m_pParent->RemoveChild(this);
m_pParent = nullptr;
return static_cast<Child*>(this);
}
...
}
//Array of CObject* pointers is no longer possible.
'Mở cửa sổ mới() 'phương pháp được sử dụng trong một cách xấu xí: ' CObject * tree_of_stuff;' - Một cây đầy đủ của các đối tượng 'CSpecificObject * specific_object = tree_of_stuff-> Trẻ em ("StringId") -> split(); ' Phương thức' Child <>() 'thực hiện tìm kiếm dọc theo cây và đưa đối tượng vào tham số mẫu được chỉ định. Cú pháp này không có sẵn nếu 'detach()' trả về 'void' hoặc' CObject * '. –
Phương thức 'duplicate()' là một nguồn lỗi nhất định, đó là một trong những lý do tôi mở rộng mẫu hiện tại bằng CRTP. Theo quan điểm của tôi, dựa vào constructor sao chép là an toàn hơn khi hứa rằng mọi người sẽ thực hiện phương thức 'duplicate()'. –