2010-07-09 19 views
7

Tôi có một chức năng mà tôi muốn một hành động dọn dẹp được thực hiện 90% thời gian, nhưng trong 10% tôi muốn thực hiện một số hành động khác.Có cách nào để thay đổi hành động xóa trên phiên bản hiện tại của shared_ptr

Có cách nào để sử dụng một số điều khiển phạm vi tiêu chuẩn như shared_ptr<> để ban đầu nó có thể có một hành động xóa và sau đó trong chức năng hành động xóa có thể được thay đổi?

shared_ptr<T> ptr(new T, std::mem_fun_ref(&T::deleteMe)); 
ptr.pn.d = std::mem_fun_ref(&T::queueMe); 
+2

Tại sao không thực thi các chiến lược xóa trong chính bản thân tùy chỉnh của bạn? – Abhay

+0

Tôi chỉ đang cố gắng tránh viết deleter tùy chỉnh khi tôi chỉ cần chọn (hiện tại) giữa 2 hàm thành viên. –

Trả lời

2

Tôi không nghĩ bạn có thể thay đổi điều chỉnh khi đã tạo shared_ptr.

Nhưng tại sao bạn lại làm điều đó? Thông thường, khi bạn tạo một đối tượng, bạn biết ngay lập tức nó phải bị phá hủy như thế nào. Điều này không có khả năng thay đổi.

Nếu bạn thực sự phải thực hiện một số phương pháp điều trị cụ thể, bạn vẫn có thể cung cấp một tùy chỉnh deleter làm những việc đặc biệt tùy thuộc vào logic yêu cầu.

+2

Tôi vừa nghĩ về một lý do, đó là bạn có thể tưởng tượng muốn thay thế các deleter bằng một deleter mới mà làm những gì cũ, * và * cái gì khác (chẳng hạn như thông báo cho người nghe về sự hủy diệt đối tượng). Nhưng tôi khá chắc chắn rằng nó không khả thi, nếu chỉ vì các deleter là trong khối điều khiển, vì vậy bạn chắc chắn không thể thay thế nó bằng một deleter với một kích thước khác nhau. Vì vậy, như bạn nói, tiềm năng cho hành vi này cần phải được trong 'shared_ptr' ngay từ đầu. –

+0

Trường hợp sử dụng tôi có thể nghĩ đến là bạn có một thư viện trả về một tiêu chuẩn :: tr1 :: shared_ptr và bạn muốn di chuyển quyền kiểm soát đến std :: shared_ptr và bạn tự tin rằng std :: shared_ptr sẽ tồn tại lâu hơn std :: tr1 :: shared_ptr. Awful? Chắc chắn rồi. –

2

Có một lý do hợp lệ để cần phải thay đổi deleter. Lấy ví dụ này:

int foo(std::shared_ptr<double>& bar) { 
    ... 
    std::shared_ptr<double> p(my_allocator<double>::allocate(), my_deleter<double>()); 
    bar.swap(p); // this copies the deleter 
    ... 
} 

int main(int, char**) { 
    std::shared_ptr<double> d; 
    foo(d); // d now has a new deleter that will be called when it goes out of scope 
    ... 
} 

Trong trường hợp này hàm foo() phân bổ đôi * sử dụng một số cấp phát đặc biệt. Nó cần phải giải phóng bộ nhớ đó một cách đặc biệt. Người gọi không cần phải biết cách giải phóng bộ nhớ.

+0

Không có gì thay đổi ở đây. Bạn đang tạo một 'std :: shared_ptr' mới, và sau đó sử dụng nó giống như bất kỳ đối tượng giá trị nào khác. –

+0

@ kuba-ober: Tôi hiểu rồi, tôi hiểu nhầm câu hỏi ban đầu của anh ấy. Bạn nói đúng, anh ta chắc chắn muốn thay đổi deleter cho con trỏ được quản lý sau khi nó được xây dựng thay vì cập nhật deleter trên một đối tượng shared_ptr hiện có (như tiêu đề nói). –

0

Điều này không có ý nghĩa gì vì có số lượng shared_ptr s quản lý quyền sở hữu giá trị. Bạn cần phải sửa đổi tất cả, và điều đó không khả thi. Đừng quên rằng một khối điều khiển là một chi tiết thực hiện, vì vậy hãy "aha, nhưng thay đổi nó trong khối điều khiển" sẽ không hoạt động.

Hành động xóa phải được kiểm soát bởi cá thể thuộc sở hữu của shared_ptr, ví dụ:

class C { 
... 
    void (C::action*)() { &C::action1 }; 
    void action1(); 
    void action2(); 
    ~C() { (this->*action)(); } 
}; 

void test() { 
    std::shared_ptr<C> a; 
    a->action = &C::action2; 
    // action2 gets invoked once `a` falls out of scope 
} 
Các vấn đề liên quan