2013-03-24 28 views
7

tôi là tạo ra một giao diện trong C++ của tôi ứng dụng và tôi có một lớp gọi là GUIObject đó là lớp cơ sở cho tất cả các thành phần khác, ví dụ như Button, CheckBox, Window, vvphương pháp tĩnh để tạo ra một đối tượng thay vì constructor

Tôi cũng có một lớp GUIObjectsStorage, bao gồm tất cả GUIObject s được tạo. Cho đến nay tôi đã làm việc với con trỏ nguyên, vì vậy tôi chỉ có constructor này cho GUIObject lớp:

GUIObject::GUIObject() : 
{ 
    GUIObjectsStorage::Instance().addObject(this); 
} 

Và nó là ok cho nhu cầu của tôi, bởi vì bất cứ khi nào tôi muốn truy cập vào đối tượng cụ thể, tôi chỉ lấy nó từ GUIObjectsStorage. Nhưng bây giờ tôi đang cố gắng để di chuyển vào sử dụng con trỏ thông minh, do đó GUIObjectsStorage tại cửa hàng loạt các std::shared_ptr<GUIObject> thay vì con trỏ thô và tôi không thể sử dụng constructor của tôi như tôi đã sử dụng nó trước:

GUIObject::GUIObject() : 
{ 
    GUIObjectsStorage::Instance().addObject(std::shared_ptr<GUIObject>(this)); 
} 

vì ví dụ :

// Somewhere in code 
std::shared_ptr<Button> bt = std::shared_ptr<Button>(new Button()); 

về cơ bản bây giờ tôi muốn có hai shared_ptr s (một ở đây, thứ hai trong GUIObjectsStorage, bởi vì nó đã được bổ sung trong Button 's constructor) mà cả hai đều có tính tham khảo = 1, nhưng cả hai điểm đến cùng một đối tượng trong trí nhớ. Sau đó, nếu một trong số họ chết, bản thân đối tượng cũng đang bị phá hủy. Vì vậy, tôi đã đưa ra một ý tưởng để có thể làm cho nhà xây dựng tư nhân cho tất cả các lớp kế thừa từ GUIObject và tạo ra một phương pháp tĩnh mà sẽ tạo ra và trả về std::shared_ptr và bản sao của nó thêm vào GUIObjectsStorage. Bằng cách này, tôi có thể có shared_ptr s với tính tham khảo = 2 đó là chính xác:

class Button : public GUIObject 
{ 
private: 
    // ... 
    Button(); 
public: 
    // ... 
    static std::shared_ptr<Button> create(); 
} 

std::shared_ptr<Button> Button::create() 
{ 
    std::shared_ptr<Button> bt = std::shared_ptr<Button>(new Button()); 
    GUIObjectsStorage::Instance().addObject(bt); 

    return bt; 
} 

Bằng cách ẩn constructor tôi có thể chắc chắn rằng không ai sẽ tạo ra một đối tượng trong cách khác nhau hơn bằng cách sử dụng phương pháp create().

Nhưng đây có phải là cách thiết kế tốt không? Nếu không, những gì có thể là một giải pháp tốt hơn cho vấn đề này?

+1

Có vẻ tốt với tôi. Ngoài ra, tôi nghĩ rằng toàn bộ điểm shared_ptr là để tránh loại vấn đề này? – Polar

+0

@Polar Thực ra tôi nghĩ rằng toàn bộ điểm của 'shared_ptr' là để tránh việc xóa các đối tượng theo cách thủ công, chứ không phải chính xác loại vấn đề này. :-) –

+0

Tôi hơi bối rối. Tại sao bạn đang cố gắng sử dụng 'shared_ptr's ở nơi đầu tiên? Bạn chỉ có thể sử dụng trực tiếp con trỏ, và tiêu diệt tất cả chúng trong 'DestIObjectsStorage''s destructor. –

Trả lời

2

Đây là ứng dụng cổ điển của Nhà máy để tạo đồ vật.

Điều đó nói rằng, bạn có thể không cần điều này. Bạn có biết khi nào các vật dụng không còn cần thiết nữa? GUI quản lý như thế này thường làm. Nếu vậy, người bình luận là đúng: chỉ định một chủ sở hữu của đối tượng, để cho nó xóa nó, và bạn được thiết lập.

0

Bạn có thể xem xét kế thừa từ enable_shared_from_this.

Sau đó, sau khi bạn có shared_ptr đối tượng, bạn có thể sử dụng shared_from_this() để lấy shared_ptr chứa đối tượng.

+0

Nhưng vấn đề là tôi chưa có bất kỳ 'shared_ptr', bởi vì tôi muốn sử dụng nó trong hàm tạo, mà trước khi xây dựng đối tượng. –

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