Sử dụng boost::optional
, bạn có thể có một điều như vậy:
// 100 lazy BigStuffs
std::vector< boost::optional<BigStuff> > v(100);
v[49] = some_big_stuff;
sẽ xây dựng 100 của lười biếng và gán một thực some_big_stuff
để v[49]
. boost::optional
sẽ không sử dụng bộ nhớ heap, nhưng sử dụng vị trí mới để tạo các đối tượng trong bộ đệm được phân bổ theo chồng. Tôi sẽ tạo ra một wrapper xung quanh boost::optional
như thế này:
template<typename T>
struct LazyPtr {
T& operator*() { if(!opt) opt = T(); return *opt; }
T const& operator*() const { return *opt; }
T* operator->() { if(!opt) opt = T(); return &*opt; }
T const* operator->() const { return &*opt; }
private:
boost::optional<T> opt;
};
này bây giờ sử dụng boost::optional
để làm chất liệu. Nó phải hỗ trợ tại chỗ xây dựng như thế này (ví dụ trên op*
):
T& operator*() { if(!opt) opt = boost::in_place(); return *opt; }
Trong đó sẽ không yêu cầu bất kỳ bản sao-ing. Tuy nhiên, hướng dẫn tăng cường hiện tại không bao gồm quá tải của toán tử gán đó. Tuy nhiên, mã nguồn. Tôi không chắc liệu đây có phải chỉ là một khiếm khuyết trong sách hướng dẫn hay liệu tài liệu của nó có bị bỏ sót hay không. Vì vậy, tôi sẽ sử dụng cách an toàn hơn bằng cách sử dụng phân công bản sao bằng cách sử dụng T()
.
Nguồn
2009-05-18 16:30:53
nó sẽ có ý nghĩa để chứa con như auto_ptr –
Nhưng làm thế nào bạn sẽ khởi tạo hộp [49] -> chiều rộng để có một giá trị khởi tạo không tầm thường (tức là, không phải 0)? Bạn có thể muốn có một giao diện cho phép hàm tạo cho * (hộp [49]) nhận chỉ mục của nó làm đối số, để nó có thể phân biệt chính nó với các hộp khác. Điều đó có nghĩa là sử dụng một cái gì đó khác với std: vector, và đặt bạn vào miền của vectơ/ma trận thưa thớt. –
Bạn thậm chí có thể sử dụng tăng :: tùy chọn thay vì con trỏ con. Sử dụng boost :: optional có nghĩa là bạn có lợi cho việc phân bổ stack của nó. Không có heap nào được sử dụng thì –