2012-03-19 23 views
7

Tôi cần phải tìm một giải pháp để cho phép một lớp con có được con trỏ thông minh thích hợp của nó.Các lớp con và get_shared_from_this()

class Parent : public enable_shared_from_this { 
    ... 
} 

class Child : public Parent { 
    public Child(){ 
    boost::shared_ptr<Parent> pointer=shared_from_this(); // should work 
    boost::shared_ptr<Child> pointer=shared_from_this(); // won't work. 

    ... 
} 

Làm cách nào để có con trỏ thông minh phù hợp sử dụng shared_from_this()?

BỐI CẢNH:

Tôi đang viết một chút thứ notifier/người nghe, và một số các lớp học sẽ tự nhiên cần phải đăng ký và unregister mình khỏi các notifier. Ví dụ,

class Body : extends Listener<BodyMessage>{ // listen for BodyMessage messages 
    public: 
    Body() { 
     Notifier<BodyMessage>::register(this); // register with the appropriate notifier 
    } 

    virtual ~Body { 
     Notifier<BodyMessage>::unregister(this); // unregister 
    } 

    bool notify(BodyMessage m){ ... } 

    ... 
} 

Thông thường tôi sẽ chỉ cần sử dụng con trỏ này, và tất cả sẽ tốt. Tôi đã nhận được Trình thông báo để sử dụng các mẫu, vì vậy tôi chỉ có thể chuyển các tin nhắn cho những người muốn nghe chúng.

Tuy nhiên, tôi muốn sử dụng con trỏ thông minh. Nếu notifier trông như thế này:

template<typename t> 
class Notifier { 
    public: 
    static void register<boost::shared_ptr<Listener<t>>> boost::shared_ptr<Listener<t>> listener); 

    ... 
} 

sau đó tôi không thể sử dụng con trỏ này nữa. Đương nhiên, tôi đã tạo Body mở rộng enable_shared_from_this:

class Body : public boost::enable_shared_from_this, public Listener<BodyMessage> { 
    public: 
    Notifier<BodyMessage>::register(get_shared_ptr()); 
    ... 
} 

Và điều đó có vẻ phù hợp với các Cơ quan. Nó không hoạt động, tuy nhiên, cho lớp con của các cơ quan (hoặc, ít nhất, nó dường như không):

class BodyChild : public Body { 
    public: 
    BodyChild(){ 
     Notifier<BodyMessage>::register(get_shared_ptr()); 
} 

khả năng vì tôi không thể bỏ shared_pointer. SO, tôi có thể làm cho một giải pháp mà

  • cho phép tôi sử dụng con trỏ chia sẻ cho người nghe (vì những người nghe cũng được sử dụng trong bối cảnh con trỏ thông minh khác),
  • phép tôi template Notifier và người nghe, sử dụng bản thân loại thông báo cho mẫu, vì vậy nó rất dễ nghe các tin nhắn cụ thể và vì vậy tôi không phải giải mã một tin nhắn, và
  • là đơn giản?

Tôi mở cho các ý tưởng khác, nhưng nếu tôi có thể làm việc này, tôi sẽ vui mừng.

+0

Funny, tôi chạy chống lại vấn đề này ngày hôm nay. Sử dụng con trỏ thông minh cho mẫu Observer hóa ra là một ý tưởng rất hay. Bạn cũng có thể sử dụng 'boost :: signal' để lấy một nửa công việc được thực hiện tự động (đặc biệt là với các đối tượng' scoped_connection'). –

+0

Tại sao bạn cần/muốn 'std :: shared_ptr' cho hệ thống trình thông báo/nghe của bạn?Liệu người nghe có thực sự được sở hữu bởi người thông báo không, để họ bị phá hủy khi tất cả các người thông báo đã biến mất? Hay thực sự có những vật thể khác, sở hữu những vật thể lắng nghe và có thể chăm sóc sự khởi tạo và xây dựng? Khi xây dựng một hệ thống như vậy, tôi đã tìm thấy nó khá hữu ích để thực sự giữ được rất nhiều kiểm soát và không cho nó đi. – LiKao

+0

@LiKao: Một cách để viết mẫu người quan sát thực sự là để người nghe giữ cho các trình thông báo còn sống, và hủy bỏ việc hủy bỏ (shared_ptr + boost :: signal là tuyệt vời để viết điều này trong <50 LOC). Ngược lại, tôi thấy rằng gắn bó với một cái gì đó rất đơn giản và cứng nhắc trong tình huống này giúp viết mã tốt hơn (đọc: duy trì được nhiều hơn). –

Trả lời

6

Bạn có thể truyền con trỏ thông minh và Boost cung cấp cho bạn một vài mẫu để giảm bớt điều này. Bạn có ví dụ. static_pointer_castdynamic_pointer_cast cho phép bạn truyền "qua" con trỏ.

Kể từ this là loại động đúng, bạn có thể gọi boost::static_pointer_cast trên giá trị trở lại của shared_from_this():

boost::shared_ptr<Child> p = static_pointer_cast<Child>(shared_from_this()); 

(không cần phải hội đủ điều kiện static_pointer_cast nhờ tra cứu Koenig)

+1

static_pointer_cast (...) có lẽ là cách tốt nhất để đi trong trường hợp này; cảm ơn. Tất nhiên, tôi nhận ra rằng tôi có thể không có cả hai con trỏ thông minh được sử dụng bởi trình thông báo và có đối tượng tự thêm vào xây dựng, bởi vì con trỏ thông minh của đối tượng không "sẵn có" cho đến khi các nhà xây dựng hoàn tất. – whiterook6

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