2013-07-08 31 views
9

Tôi đang cố gắng sắp xếp các đối tượng bằng cách sử dụng std::shared_ptrstd::weak_ptr. Kịch bản giống như sau:shared_ptr & weak_ptr chuyển đổi

Tôi có các đối tượng thuộc lớp channel được bắt nguồn từ lớp trừu tượng abstract::channel (với các hàm ảo thuần túy). Tôi có một vùng chứa channelContainer (std::vector) có chứa các con trỏ được chia sẻ (std::shared_ptr) đến channel Đối tượng.

Bây giờ, tôi có deque (std::deque) chứa các con trỏ yếu (std::weak_ptr) cho mỗi đối tượng trong số channelContainer. Cho phép đặt tên cho deque này freeChannelQueue.

Vì vậy, cho phép nói rằng: 'Làm thế nào để chuyển đổi một tham chiếu đến một đối tượng để một con trỏ yếu'

std::vector<std::shared_ptr<abstract::channel> > channelContainer; 
std::deque<std::weak_ptr<abstract::channel > > freeChannelQueue; 

//Assuming that both the containers are filled appropriately How do I go about implementeing the below functions? 

abstract::channel& get_free_channel() { 
    //This should return a free channel object from 'freeChannelQueue' and pop the queue. 
} 

bool release_channel(abstract::channel& ch) { 
//This should convert 'ch' to a std::weak_ptr (or std::shared_ptr) and push it to 'freeChannelQueue' 
} 

tôi đặc biệt quan tâm đến

+0

AFAIK bạn không thể khởi tạo/xây dựng một 'weak_ptr' từ một đối tượng hoặc tham chiếu đối tượng trực tiếp vì đối tượng mà nó tham chiếu phải được sở hữu bởi' shared_ptr'. Do đó bạn cần 'shared_ptr' hoặc' weak_ptr' để xây dựng. – Piotr99

Trả lời

1

Đây có phải là thiết kế của bạn không? Như vậy, có một số vấn đề nghiêm trọng về tuổi thọ của kênh. Ví dụ - nếu mã gọi get_free_channel() thì khai báo của bạn trả về cho chúng một tham chiếu đến một đối tượng, nhưng chúng không có cách nào để đảm bảo tuổi thọ của nó bao gồm việc sử dụng chúng. Đó thể không quan trọng phụ thuộc vào những gì các mã khách hàng là bạn đang gọi hàm từ, nhưng có thể bạn muốn quay trở lại một shared_ptr, như trong:

std::shared_ptr<abstract::channel> get_free_channel() 
{ 
    // return free channel from 'freeChannelQueue' and pop the queue 

    // take a scoped lock on the free queue if necessary 

    while (!freeChannelQueue.empty()) 
    { 
     auto p_channel = freeChannelQueue.back(); 
     freeChannelQueue.pop_back(); 
     std::shared_ptr<abstract::channel> p = p_channel.lock(); 
     if (p) return p; 
    } 

    // freeChannelQueue empty... throw or return nullptr etc.. 
} 

Về "phát hành" ...

bool release_channel(abstract::channel& ch) { 
//This should convert 'ch' to a std::weak_ptr (or std::shared_ptr) and push it to 'freeChannelQueue' 
} 

Như vậy, điều này chỉ có thể xảy ra nếu bạn tìm kiếm channelContainer để tìm đối tượng sau đó nhận được weak_ptr hoặc shared_ptr từ đó. Một lần nữa - có lẽ bạn nên thay đổi nguyên mẫu sao cho nó nhận trực tiếp số shared_ptr hoặc weak_ptr, khóa hàng đợi miễn phí sau đó đẩy con trỏ thông minh lên ....

Tất cả, rất khó để cung cấp cho bạn lời khuyên hữu ích mà không hiểu cách tuổi thọ kênh của bạn sẽ được quản lý và các chủ đề khác nhau có thể cố gắng sử dụng các đối tượng và hàng đợi như thế nào. Tôi hy vọng những điều trên giúp một chút, ngay cả khi chỉ hỏi một câu hỏi chính xác hơn.

+0

Cảm ơn câu trả lời, bây giờ tôi đã nhận được câu trả lời cho vấn đề của mình. Vẫn không chắc chắn về thiết kế, sẽ cập nhật câu hỏi nếu tôi thấy thiết kế hiện tại không phù hợp với nhu cầu của tôi! – user2559933

+0

@ user2559933: chắc chắn ... chúc bạn may mắn với nó. –

+0

Bạn có thể chuyển đổi một con trỏ thô hoặc tham chiếu đến shared_ptr nếu bạn thêm std :: enable_shared_from_this làm lớp cơ sở; bạn có thể cung cấp cho lớp trừu tượng một hàm thành viên trả về một shared_ptr cho chính nó. – Dennis

3

Bạn có thể không

chuyển đổi một tham chiếu đến một đối tượng để một con trỏ yếu

Bạn có thể làm cho một con trỏ yếu từ một con trỏ được chia sẻ, chỉ sử dụng phân = ví dụ

std::shared_ptr<abstract::channel> get_free_channel(); 

sau đó

bool release_channel(std::shared_ptr<abstract::channel> ch) 
{ 
    std::weak_ptr<abstract::channel> weak_ch = ch; 
    //... 
} 

Coi chừng kiếp - shared_ptr sẽ đi trước mặt các con trỏ trỏ yếu đối với họ?

0

Tôi hiểu câu hỏi của bạn như sau: bạn có một vùng chứa chứa tất cả các đối tượng kênh và bạn có vùng chứa thứ hai để duy trì thứ tự các ứng dụng của bạn có thể sử dụng kênh nào. Sau đó, bạn sẽ thích một giao diện để trả lại tham chiếu đến kênh miễn phí tiếp theo cho khách hàng của mình và khi khách hàng hoàn tất, nó sẽ phát hành kênh trở lại vùng chứa.

Để tham chiếu đến kênh, bạn có thể sử dụng lock để tạo shared_ptr từ weak_ptr và sau đó dereference (chỉ cần không xóa đối tượng bên dưới!). Tuy nhiên, tôi không thấy một cách hợp lý để đi theo cách khác, bạn sẽ cần phải tìm kiếm vùng chứa kênh của bạn cho đối tượng phù hợp và tạo ra một con trỏ yếu từ shared_ptr phù hợp một lần nữa.

Tôi sẽ xem xét không sử dụng weak_ptr và tham chiếu chút nào, chỉ cần gắn với shared_ptr. Vì bạn sử dụng deque để duy trì kênh nào có sẵn, thay vào đó bạn chỉ có thể giữ shared_ptr có sẵn ở đó. Nếu bạn hài lòng rằng khách hàng của bạn sẽ luôn phát hành các kênh khi kết thúc, bạn có thể không cần một thùng chứa cho tất cả các đối tượng, chỉ deque cho các kênh miễn phí - phụ thuộc vào thiết kế tổng thể của bạn.

Như những người khác đã nói, bạn cần phải xem xét tuổi thọ của các đối tượng kênh của bạn và cách chúng được khách hàng sử dụng.

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