2012-02-06 10 views
6

Tôi có một lớp, có đối tượng boost::asio::io_service. Tôi muốn đối tượng này được lưu trữ trong một số boost::shared_ptr.Khởi tạo Boost shared_ptr trong hàm tạo

Vì vậy, tiêu đề của tôi trông như thế này (tôi đã thoát khỏi bất kỳ mã không cần thiết vì vậy nó không đánh lạc hướng)

class CommandDispatcher 
{ 
private: 
    boost::shared_ptr<boost::asio::io_service> m_ioservice; 
public: 
    CommandDispatcher(); 
}; 

Khi tôi bây giờ tạo một đối tượng của CommandDispatcher Tôi muốn rằng một đối tượng io_service được khởi tạo cho con trỏ. Bây giờ tôi không hoàn toàn chắc chắn làm thế nào để làm điều này. Tôi nhìn lên hai differentsolutions nhưng chỉ có một là làm việc và tôi không khá chắc chắn nếu nó là một trong những tốt đẹp. Nhưng hãy xem cho chính mình:

CommandDispatcher::CommandDispatcher() 
{ 
    m_ioservice.reset(new boost::asio::io_service);   // this actually works 
    //m_ioservice = boost::make_shared<boost::asio::io_service> 
    // (new boost::asio::io_service);      // this doesn't work 
} 

Vì vậy, cuộc gọi reset đang hoạt động, nhưng tôi nghĩ rằng cuộc gọi này thực sự là gán lại con trỏ. Vì vậy, nó là không sai để sử dụng nó nhưng nó không có vẻ giống như giải pháp tốt nhất cho tôi. Đề xuất cho cuộc gọi make_shared tôi đã tìm thấy trong một câu hỏi khác. Nhưng điều này chỉ sẽ không làm việc cho tôi (tôi đã thực hiện nó như được mô tả trong ví dụ tăng chính thức). Tôi nhận được

/usr/local/include/boost/smart_ptr/make_shared.hpp:189: error: invalid conversion from ‘boost::asio::io_service*’ to ‘size_t’

/usr/local/include/boost/smart_ptr/make_shared.hpp:189: error: initializing argument 1 of ‘boost::asio::io_service::io_service(size_t)’

Tôi không khá chắc chắn làm thế nào để làm điều này bây giờ, đó sẽ là cách tốt nhất (có thể có một hoàn chỉnh tùy chọn khác để làm điều đó). Hoặc có lẽ tôi đang làm đúng, nhưng tôi gettin một cái gì đó với io_service sai.

Hy vọng câu hỏi này chưa có ở đây theo cách này (tôi đã tra cứu một số câu hỏi cũ, nhưng không có câu trả lời nào phù hợp với tôi).

+0

Tại sao các biến riêng tư được liệt kê trước phương pháp công khai? Chắc chắn giao diện công cộng quan trọng hơn chi tiết thực hiện riêng tư? :)

+0

Tôi thực sự nghĩ (và đã học một số thời gian trước đây) rằng đó là "giai điệu tốt" để khai báo biến thành viên công khai và riêng tư và sau đó khai báo phương thức công cộng và riêng tư. – Toby

+0

Tôi nghĩ rằng hầu hết mọi người sẽ quan tâm hơn đến giao diện công khai, trái ngược với những biến mà bạn sử dụng để đạt được nó. –

Trả lời

7
CommandDispatcher::CommandDispatcher() 
    : m_ioservice(new boost::asio::io_service) // ver 1. this is how you should do it. 
{ 
    //m_ioservice.reset(new boost::asio::io_service); // ver 2  
    //m_ioservice = boost::make_shared<boost::asio::io_service>(); // ver 3 
} 
+0

Vâng điều này hoạt động (và có vẻ tốt đẹp) nhưng những gì tôi không hiểu là nơi sự khác biệt giữa cuộc gọi này là và 'm_ioservice = mới tăng :: asio :: io_service' mà thực sự không hoạt động ??? – Toby

+0

Cuộc gọi nào là "cuộc gọi này"? – ronag

+0

Haha xin lỗi vì đã xây dựng nó một chút mơ hồ. Nếu u nói 'CommandDispatcher :: CommandDispatcher(): m_ioservice (mới tăng :: asio :: io_service)' không phải là giống như sayin 'CommandDispatcher :: CommandDispatcher() {m_ioservice = new boost :: asio :: io_service; } '? – Toby

8

Nếu bạn đang sử dụng make_shared, thì bạn không tự sử dụng new; bạn truyền nó cho các đối số hàm tạo và nó sẽ tạo đối tượng cho bạn. Trong trường hợp này, không có lý lẽ, vì vậy chỉ cần làm:

m_ioservice = boost::make_shared<boost::asio::io_service>(); 

mặc dù nó sẽ đẹp hơn để khởi nó trong danh sách initialiser chứ không phải là cơ thể constructor:

CommandDispatcher::CommandDispatcher() : 
    m_ioservice(boost::make_shared<boost::asio::io_service>()) 
{ 
} 

Sử dụng make_shared có lợi thế rằng nó sẽ chỉ thực hiện phân bổ bộ nhớ duy nhất, trong khi khởi tạo bằng cách sử dụng new boost::asio::io_service sẽ yêu cầu hai (một cho đối tượng và một cho số tham chiếu được chia sẻ).

1

Các đẹp cách có lẽ là

CommandDispatcher::CommandDispatcher() : 
    m_ioservice(new boost::asio::io_service) 
{ 
} 

vì thay thế có bạn mặc-xây dựng shared_ptr đầu tiên, và sau đó giao lại nó.

Hoặc, tương đương sử dụng make_shared:

CommandDispatcher::CommandDispatcher() : 
    m_ioservice(boost::make_shared<boost::asio::io_service>()) 
{ 
} 
0

Có một số cách:

  • để khởi tạo đơn giản, tạo ra trong danh sách của constructor:

.

CommandDispatcher::CommandDispatcher() : 
    m_ioservice(new boost::asio::io_service) 
{ 
} 
  • cho dependency injection sử dụng một nhà máy:

.

CommandDispatcher::CommandDispatcher() : 
    m_ioservice(Factory::Create()) 
{ 
} 
  • cho dependency injection sử dụng bằng cách thông qua đối tượng đã được tạo ra:

.

CommandDispatcher::CommandDispatcher(boost::shared_ptr<boost::asio::io_service> service) : 
    m_ioservice(service) 
{ 
}