Khi nào / tại sao tôi muốn xóa phương thức khởi tạo của mình một cách rõ ràng? Giả sử lý do là để ngăn chặn việc sử dụng nó, tại sao không chỉ làm cho nó private?
class Foo
{
public:
Foo() = delete;
};
Khi nào / tại sao tôi muốn xóa phương thức khởi tạo của mình một cách rõ ràng? Giả sử lý do là để ngăn chặn việc sử dụng nó, tại sao không chỉ làm cho nó private?
class Foo
{
public:
Foo() = delete;
};
delete. Cả câu hỏi và câu trả lời của Luchian đều dễ dàng được coi là mang tính xây dựng. Bất cứ ai không hiểu những điểm tốt hơn của C ++ 11 nhưng sẽ cần sớm nhận được điều gì đó từ cả hai.
Câu trả lời:
Làm thế nào về:
//deleted constructor
class Foo
{
public:
Foo() = delete;
public:
static void foo();
};
void Foo::foo()
{
Foo f; //illegal
}
đấu với
//private constructor
class Foo
{
private:
Foo() {}
public:
static void foo();
};
void Foo::foo()
{
Foo f; //legal
}
Về cơ bản chúng là những thứ khác nhau. privatecho bạn biết rằng chỉ các thành viên của lớp mới có thể gọi phương thức đó hoặc truy cập vào biến đó (hoặc tất nhiên là bạn bè). Trong trường hợp này, việc một staticphương thức của lớp đó (hoặc bất kỳ thành viên nào khác) gọi một phương thức privatekhởi tạo của một lớp là hợp pháp. Điều này không áp dụng cho các hàm tạo đã xóa.
Mẫu ở đây .
tại sao xóa rõ ràng hàm tạo?
Một lý do khác:
Tôi sử dụng deletekhi tôi muốn đảm bảo rằng một lớp được gọi bằng bộ khởi tạo. Tôi coi đó là một cách rất thanh lịch để đạt được điều này mà không cần kiểm tra thời gian chạy.
Trình biên dịch C ++ thực hiện việc kiểm tra này cho bạn.
class Foo
{
public:
Foo() = delete;
Foo(int bar) : m_bar(bar) {};
private:
int m_bar;
}
Mã này - rất đơn giản - đảm bảo rằng không có sự khởi tạo như thế này:Foo foo;
Foocó nhiều hàm tạo, không phải là mặc định, thì Foo foo;sẽ gây ra lỗi lâu hơn nữa khi liệt kê tất cả các hàm tạo được xác định ngầm, được bảo vệ và riêng mà nó không khớp.
Tôi đã gặp các ctors mặc định được khai báo là 'đã xóa' trong mã nguồn của LLVM (trong AlignOf.h chẳng hạn). Các mẫu lớp được liên kết thường nằm trong một không gian tên đặc biệt được gọi là 'llvm :: detail'. Toàn bộ mục đích ở đó tôi nghĩ là họ chỉ coi lớp đó như một lớp trợ giúp. Họ không bao giờ có ý định tạo chúng; chỉ để sử dụng chúng trong ngữ cảnh của các mẫu lớp khác với một số thủ thuật lập trình siêu mẫu chạy trong thời gian biên dịch.
Ví dụ. có mẫu lớp AlignmentCalcImpl này chỉ được sử dụng trong một mẫu lớp khác được gọi là AlignOf làm tham số cho toán tử sizeof (.). Biểu thức đó có thể được đánh giá trong thời gian biên dịch; và không cần khởi tạo mẫu -> vậy tại sao không khai báo xóa ctor mặc định để thể hiện ý định này.
Nhưng đó chỉ là giả định của tôi.
= default, thậm chí không phải lớp nào cũng có thể sử dụng nó, và cá nhân tôi thích thấy Sử dụng hàm đã xóa hơn. trên Chức năng là riêng tư. Trước đây khẳng định rõ ràng "Điều này không có nghĩa là được sử dụng." Nếu bất cứ điều gì xuất hiện từ đó, lớp không thể sử dụng nó thực sự tạo ra sự khác biệt về ngữ nghĩa.