struct A
{
A(const A& arg) : data(arg.data)
{
do_something_special();
}
// by writing copy constructor, we suppress the generation of
// implicit default constructor A::A()
int data;
};
void foo1()
{
A a; // does not work, since there's no default constructor
}
Hãy nói rằng constructor mặc định của chúng tôi không làm bất cứ điều gì đặc biệt và là (nhiều hơn hoặc ít hơn) bằng để trình biên dịch tạo ra một. Chúng tôi có thể sửa chữa nó bằng một trong hai cách viết constructor mặc định của chúng ta (mà có thể nhận được tẻ nhạt nếu lớp của chúng ta có nhiều thành viên không tĩnh), hoặc bằng cách sử dụng các = default
cú pháp:
struct A
{
A() = default;
A(const A& arg) : data(arg.data)
{
do_something_special();
}
int data;
};
Xóa chức năng rất hữu ích khi chúng ta muốn cấm sử dụng các tình trạng quá tải hoặc mẫu chuyên biệt cụ thể hoặc chỉ để cấm các đối tượng sao chép (hoặc di chuyển).
void foo(char c) {}
void foo(int i) = delete; // do not allow implicit int -> char conversion
Khi bạn muốn cấm sao chép (ví dụ: đối tượng thread), cách thành ngữ thông thường là để khai báo constructor sao chép tin mà không cần thực hiện (yeah, hoặc sử dụng tăng :: noncopyable). Trong khi điều này làm việc cho hầu hết các trường hợp, đôi khi bạn có thể gặp phải một số lỗi liên kết tối nghĩa. Hãy xem xét:
struct A
{
A() = default;
friend void foo();
private:
A(const A&);
};
void foo()
{
A a;
A b(a); // results in linker error in gcc
}
Xóa A(const A&)
xóa, chúng tôi tránh lỗi liên kết tiềm ẩn và thực hiện ý định của chúng tôi (không cho phép sao chép) rất rõ ràng.
@Christian: Nếu chúng ta chỉ đơn giản là có 'struct S {S (int) {}}; ', sự hiện diện của' S (int) 'sẽ ngăn chặn hàm tạo mặc định được khai báo ngầm định. –
Các quy tắc cho POD đã được thoải mái trong C++ 0x/11 vì vậy ví dụ thứ hai của bạn cũng sẽ là một POD trong C++ 0x/11. Bạn cũng có thể sử dụng các đặc điểm mới :: is_pod để tự kiểm tra bằng một khẳng định tĩnh chẳng hạn. –
David
@David: Các quy tắc cho POD thực sự đã được thư giãn, nhưng thứ hai 'S' vẫn không phải là POD. Cấu trúc POD phải là một lớp tầm thường. Một lớp tầm thường phải có một hàm tạo mặc định tầm thường. Một hàm tạo mặc định do người dùng cung cấp không phải là tầm thường. Chữ 'S' thứ hai có một hàm tạo mặc định do người dùng cung cấp và do đó không phải là POD. –