2011-04-01 51 views
162
class my_class 
{ 
    ... 
    my_class(my_class const &) = delete; 
    ... 
}; 

Có nghĩa là gì trong ngữ cảnh đó?Ý nghĩa của = xóa sau khi khai báo hàm

Có bất kỳ "công cụ sửa đổi nào khác" (không phải là = 0= delete) không?

+7

Tôi khá chắc chắn đó không phải là tiêu chuẩn C++ ... – Blindy

+0

Nơi mà bạn đã nhận được mã này? –

+19

@Blindy Nó sẽ là tiêu chuẩn trong C++ 0x, tức là sớm thôi. –

Trả lời

130

Xóa một chức năng là a C++11 feature:

Các thành ngữ phổ biến của "cấm sao chép" bây giờ có thể được thể hiện trực tiếp:

class X { 
    // ... 
    X& operator=(const X&) = delete; // Disallow copying 
    X(const X&) = delete; 
}; 

[...]

Các "xóa "cơ chế có thể được sử dụng cho bất kỳ chức năng nào. Ví dụ, chúng ta có thể loại bỏ một chuyển đổi không mong muốn như thế này:

struct Z { 
    // ... 

    Z(long long);  // can initialize with an long long   
    Z(long) = delete; // but not anything less 
}; 
+0

Không phải là phương pháp truyền thống để "cấm sao chép" chỉ để sao chép ctor và toán tử = "riêng tư?" Điều này đi xa hơn một chút và hướng dẫn trình biên dịch thậm chí không tạo ra các hàm. Nếu cả hai đều là riêng tư và = xóa, sao chép có bị cấm kép không? –

+2

@Reb, '= delete' làm cho phương thức không truy cập được ngay cả từ các ngữ cảnh có thể thấy các phương thức' riêng tư' (nghĩa là trong lớp và bạn bè của nó). Điều này sẽ loại bỏ bất kỳ sự không chắc chắn nào khi bạn đọc mã. @ Prasoon, ví dụ thứ hai đó vẫn chỉ xóa các nhà xây dựng - nó sẽ rất hay khi thấy một toán tử 'long long()' bị xóa. –

0

Đây là điều mới trong tiêu chuẩn C++ 0x nơi bạn có thể xóa một chức năng di truyền.

+8

Bạn có thể xóa bất kỳ chức năng nào. Ví dụ: 'void foo (int); template void foo (T) = delete; 'dừng tất cả các chuyển đổi ngầm định. Chỉ các đối số của kiểu 'int' mới được chấp nhận, tất cả các đối số khác sẽ cố gắng khởi tạo một hàm" đã xóa ". – UncleBens

58
  1. = 0 có nghĩa là một hàm thuần ảo và bạn không thể khởi tạo đối tượng từ lớp này. Bạn cần phải lấy ra từ nó và thực hiện phương thức này
  2. = delete có nghĩa là trình biên dịch sẽ không tạo ra các hàm tạo đó cho bạn. AFAIK này chỉ được phép trên nhà xây dựng bản sao và toán tử gán. Nhưng tôi không giỏi về tiêu chuẩn sắp tới.
+3

Có một số cách sử dụng khác của cú pháp '= xóa'. Ví dụ: bạn có thể sử dụng nó để loại bỏ một cách rõ ràng một số loại chuyển đổi tiềm ẩn có thể xảy ra với cuộc gọi. Đối với điều này, bạn chỉ cần xóa các chức năng quá tải. Hãy xem trang Wikipedia trên C++ 0x để biết thêm thông tin. – LiKao

+0

Tôi sẽ làm điều đó ngay sau khi tôi tìm thấy một số. Đoán nó nó thời gian để bắt kịp với c + + 0X – mkaes

+0

Vâng, C + + 0x đá. Tôi không thể chờ GCC 4.5+ trở nên phổ biến hơn, vì vậy tôi có thể bắt đầu sử dụng lambdas. – LiKao

1

Chuẩn C++ 0x mới. Vui lòng xem phần 8.4.3 trong N3242 working draft

+0

Whoa, bản nháp đó đã lỗi thời. Đây là thông tin mới nhất (tính đến ngày 3 tháng 4 năm 2011): http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf – TonyK

+0

Cảm ơn và cập nhật liên kết. Rất hữu ích để có được bản nháp hiện tại. Phần/nội dung được tham chiếu đã chính xác ngay cả trong bản nháp cũ nên tôi không hiểu phiếu bầu xuống. – dubnde

+0

Đã xóa, bây giờ bạn đã cập nhật liên kết :-) – TonyK

1

= delete là một tính năng được giới thiệu trong C++ 11. Theo =delete nó sẽ không được phép gọi hàm đó.

Chi tiết.

Giả sử trong một lớp học.

Class ABC{ 
Int d; 
Public: 
    ABC& operator= (const ABC& obj) =delete 
    { 

    } 
}; 

Trong khi gọi chức năng này cho bài tập obj, nó sẽ không được phép. Có nghĩa là toán tử gán sẽ hạn chế sao chép từ một đối tượng này sang đối tượng khác.

3

trích đoạn này từ C++ Programming Language [Phiên bản 4] - Bjarne Stroustrup cuộc đàm phán cuốn sách về các mục đích thực sự đằng sau sử dụng =delete:

Sử dụng bản mặc định hoặc di chuyển cho một lớp trong một hệ thống phân cấp thường là thảm họa: chỉ cho một con trỏ tới chân đế, chúng tôi không biết thành viên nào là lớp học bắt nguồn (§3.2.2), vì vậy chúng tôi không thể biết cách sao chép chúng.Vì vậy, điều tốt nhất để làm thường là để xóa các bản sao mặc định và di chuyển hoạt động, có nghĩa là, để loại bỏ các định nghĩa mặc định của hai hoạt động:

class Shape { 
public: 
    Shape(const Shape&) =delete; // no copy operations 
    Shape& operator=(const Shape&) =delete; 

    Shape(Shape&&) =delete; // no move operations 
    Shape& operator=(Shape&&) =delete; 
    ˜Shape(); 
    // ... 
}; 

Bây giờ một nỗ lực để sao chép một Shape sẽ bị bắt bởi trình biên dịch.

Cơ chế =delete là nói chung, có nghĩa là, nó có thể được sử dụng để ngăn chặn bất kỳ hoạt động

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