Trong bài này https://stackoverflow.com/a/17204598/260127, tôi có nhận xét:
Trong C++ 11 bạn thực sự sẽ muốn làm virtual ~A() = default;
Nếu không, bạn sẽ mất các nhà thầu implict di chuyển.
Nhận xét không đúng.
Thậm chí default
ed, destructor đó là "sử dụng tuyên bố" (mặc dù lưu ý rằng nó không phải là cũng "dùng cung cấp").
#include <iostream>
struct Helper
{
Helper() {}
Helper(const Helper& src) { std::cout << "copy\n"; }
Helper(Helper&& src) { std::cout << "move\n"; }
};
struct A
{
virtual ~A() {}
Helper h;
};
struct B
{
virtual ~B() = default;
Helper h;
};
struct C
{
Helper h;
};
int main()
{
{
A x;
A y(std::move(x)); // outputs "copy", because no move possible
}
{
B x;
B y(std::move(x)); // outputs "copy", because still no move possible
}
{
C x;
C y(std::move(x)); // outputs "move", because no user-declared dtor
}
}
+ g ++ - 4,8 -std = C++ 11 -O2 Wall main.cpp -pthread
+ ./a.out
bản sao
bản sao
di chuyển
Vì vậy, bạn chưa "mất" bất cứ điều gì — không có mo đã có chức năng ở đó để bắt đầu!
Dưới đây là những đoạn văn tiêu chuẩn mà cấm một constructor chuyển ngầm trong cả trường hợp:
[C++11: 12.8/9]:
Nếu định nghĩa của một lớp X
không tuyên bố một cách rõ ràng một constructor di chuyển, người ta sẽ được khai báo ngầm như mặc định khi và chỉ khi
X
không có một người dùng tuyên bố constructor sao chép,
X
không có một toán tử gán bản sao do người dùng khai báo,
X
không có một toán tử gán di chuyển do người dùng khai báo,
X
không có một destructor sử dụng tuyên bố và
- các nhà xây dựng di chuyển sẽ không được định nghĩa rõ ràng là đã bị xóa.
Bootnote
Nó sẽ không làm tổn thương nếu một phiên bản tương lai của tiêu chuẩn thực sự liệt kê những ý nghĩa chính xác của thuật ngữ như "sử dụng tuyên bố". Có nghĩa là, ít nhất, điều này:
[C++11: 8.4.2/4]:
[..] Một hàm thành viên đặc biệt là dùng cung cấp nếu nó là do người dùng khai báo và không rõ ràng mặc định hoặc xóa trên tuyên bố đầu tiên của mình. [..]
Người ta có thể giả định sự khác biệt ở đây bằng hàm ý.
Nguồn
2013-06-20 19:33:17
+1 vì bạn đã tạo ra câu trả lời sai từ 10 nghìn người dùng. –
Lưu ý rằng bạn luôn có thể nhận được hàm khởi tạo di chuyển bằng cùng một cơ chế: 'A (A &&) = mặc định; ' – Xeo