Các quy tắc để tự động tạo các hàm di chuyển đặc biệt (hàm tạo và toán tử gán) trong C++ 11 xác định rằng không có khai báo nào. Logic có lẽ là, nếu bạn cần phải làm một cái gì đó đặc biệt trong sự hủy diệt, một động thái có thể không an toàn.C++ 11 destructors ảo và tự động tạo các chức năng di chuyển đặc biệt
Tuy nhiên, đối với các cuộc gọi destructor đúng trong đa hình, cần khai báo lớp hủy của lớp cơ sở là ảo (nếu không xóa một thể hiện của lớp con thông qua con trỏ của lớp cơ sở của nó sẽ không đúng chuỗi hủy).
Tôi giả sử, sau đó, ngay cả một destructor trống sẽ ngăn trình biên dịch tự động tạo ra một chức năng di chuyển đặc biệt. Như trong:
class Base {
virtual ~Base() { }
};
Bạn có thể, tuy nhiên, mặc định destructor, như trong:
class Base {
virtual ~Base() = default;
}
Vì vậy, câu hỏi 1: Điều này sẽ cho phép trình biên dịch để tự động tạo ra các chức năng di chuyển đặc biệt không?
Có sự cố với trình phá hủy mặc định rõ ràng. Trong ít nhất là trường hợp của GCC 4.8.2, chữ ký được thay đổi hoàn toàn thành noexcept. Như trong:
class Base {
virtual ~Base() = default; // compiler changes to:
// virtual ~Base() noexcept;
}
Trong khi tôi không có vấn đề với noexcept trong một destructor, điều này sẽ phá vỡ các "khách hàng" đoạn mã sau:
class Sub : public Base {
virtual ~Sub(); // this declaration is now "looser" because of no noexcept
}
Vì vậy, câu hỏi 2 là hơn vào vấn đề: là có một cách để cho phép tự động tạo ra các hàm di chuyển đặc biệt trong C++ 11 và cho phép các chuỗi hàm hủy phù hợp với các lớp con (như được mô tả ở trên), tất cả mà không phá vỡ lớp con ("client")?
Tại sao '~ Sub' lỏng hơn? Các trình phá hủy không có các đặc tả ngoại lệ mặc định là 'noexcept'. – Pradhan
Câu hỏi dường như được xác định rõ ràng, nhưng không quan tâm, bạn có ví dụ về lý do tại sao điều này có thể cần thiết không? Điều này có vẻ giống như một hỗn hợp kỳ lạ về giá trị và ngữ nghĩa tham chiếu. Dường như với tôi như trong trường hợp bạn muốn sử dụng di chuyển (hoặc thậm chí sao chép), bạn sẽ không muốn hành vi đa hình. Và hơn thế nữa, bản sao mặc định hoặc di chuyển chắc chắn sẽ không có bất kỳ hành vi đa hình nào. – tahsmith
@tahsmith mục đích là để làm lại các lớp cơ sở theo cách mà chúng và các lớp con của chúng có thể tận dụng các ngữ nghĩa di chuyển mà không phá vỡ các lớp con. – notlesh