2013-05-13 23 views
5

Tôi muốn tạo một thùng chứa quản lý các đối tượng lớn thực hiện các bản sao sâu trên bản sao xây dựng và gán bản sao.Các thành viên di chuyển được tạo mặc định làm gì?

template <class TBigObject> 
class Container : public std::vector< std::shared_ptr<TBigObject> > 
{ 
public: 
    Container(int nToAllocate){ /* fill with default constructed TBigObjects */ } 
    Container(const Container& other){ /* deep copy */ } 
    Container(Container&&) = default; 
    Container& operator = (const Container& population){ /* deep copy */ } 
    Container& operator = (Container&&) = default; 
}; 

Tôi muốn biết những gì làm defaulted:

Container(Container&&) = default; 
Container& operator = (Container&&) = default; 

thành viên thực sự làm.

Nếu tôi gọi:

Container<int> makeContainer() 
{ 
    ... 
} 

và thiết lập breakpoint gỡ lỗi tại địa chỉ:

Container<int> moveAssigned; 
moveAssigned = makeContainer(); // EDIT corrected thanks to Andy Prowl 
Container<int> moveConstructed(makeContainer()); 

và bên trong constructor sao chép và toán tử gán, trình gỡ lỗi nhảy qua những breakpoint. Vì vậy, có vẻ như các thành viên di chuyển mặc định thực sự không thực hiện các bản sao sâu và di chuyển tất cả các subobject.

Hành vi này có được đảm bảo theo tiêu chuẩn không? Các thành viên di chuyển mặc định có hoạt động trực giác và di chuyển tất cả các subobject không?

+5

Bạn không được kế thừa từ các loại tiêu chuẩn (trừ khi được phép rõ ràng). – bitmask

+0

@bitmask Nhưng tôi không muốn có hành vi đa hình hoặc bất kỳ chức năng phức tạp nào. Tôi chỉ muốn thêm chức năng sao chép sâu. Có cách nào mà điều này có thể khiến tôi trở nên tồi tệ hơn không? Bạn có một số tài nguyên về vấn đề này không? –

+0

Tôi đoán, trong trường hợp của tôi, câu hỏi này http://stackoverflow.com/questions/4353203/thou-shalt-not-inherit-from-stdvector áp dụng –

Trả lời

8

Thành viên di chuyển mặc định có hoạt động trực giác và di chuyển tất cả các subobject không?

Có. Mỗi đoạn 12,7/15 của C++ 11 Tiêu chuẩn:

Các ngầm định nghĩa sao chép/di chuyển constructor cho một lớp X phi công đoàn thực hiện một bản sao memberwise/di chuyển các căn cứ và các thành viên của nó. [...]

By the way, đây:

Container<int> moveAssigned = makeContainer(); 

không một nhiệm vụ di chuyển, nhưng một công trình di chuyển mà sử dụng cú pháp sao chép khởi tạo. Một nhiệm vụ di chuyển sẽ là:

Container<int> moveAssigned; 
// ... 
moveAssigned = makeContainer(); // <== MOVE ASSIGNMENT HERE 

Sự khác biệt giữa điều này:

Container<int> c(make_container()); 

Và đây:

Container<int> c = make_container(); 

khái niệm, trong trường hợp thứ hai một tạm đối tượng của kiểu Container<int> được xây dựng đầu tiên từ biểu thức ở phía bên tay phải, và sau đó c được di chuyển xây dựng từ tạm thời này.

Trong trường hợp đầu tiên, bạn có khởi tạo trực tiếp, nghĩa là c sẽ được tạo trực tiếp từ đối tượng được trả về make_container().Lý do tôi nhấn mạnh từ "khái niệm" là, trong thực tế, trình biên dịch được phép thực hiện sao chép bản sao, vì vậy phiên bản thứ hai có khả năng được tối ưu hóa thành phiên bản đầu tiên (mặc dù khả năng truy cập của trình tạo bản sao hoặc di chuyển hàm khởi tạo vẫn phải được kiểm tra bởi trình biên dịch).

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