เมื่อไร / เหตุใดฉันจึงต้องการลบตัวสร้างของฉันอย่างชัดเจน สมมติว่าเหตุผลคือเพื่อป้องกันการใช้งานทำไมไม่ทำให้มันprivate?
class Foo
{
public:
Foo() = delete;
};
เมื่อไร / เหตุใดฉันจึงต้องการลบตัวสร้างของฉันอย่างชัดเจน สมมติว่าเหตุผลคือเพื่อป้องกันการใช้งานทำไมไม่ทำให้มันprivate?
class Foo
{
public:
Foo() = delete;
};
deleteแท็กคอนสตรัคสำหรับ ทั้งคำถามและคำตอบของ Luchian ถือว่าสร้างสรรค์ได้อย่างง่ายดาย ใครก็ตามที่ไม่ได้หายใจประเด็นปลีกย่อยของ C ++ 11 แต่จะต้องทำในไม่ช้าจะได้รับบางสิ่งจากทั้งสองอย่าง
คำตอบ:
เกี่ยวกับ:
//deleted constructor
class Foo
{
public:
Foo() = delete;
public:
static void foo();
};
void Foo::foo()
{
Foo f; //illegal
}
เทียบกับ
//private constructor
class Foo
{
private:
Foo() {}
public:
static void foo();
};
void Foo::foo()
{
Foo f; //legal
}
โดยพื้นฐานแล้วมันต่างกัน privateบอกคุณว่ามีเพียงสมาชิกในชั้นเรียนเท่านั้นที่สามารถเรียกใช้เมธอดนั้นหรือเข้าถึงตัวแปรนั้นได้ (หรือเพื่อน ๆ แน่นอน) ในกรณีนี้เป็นเรื่องถูกกฎหมายสำหรับstaticเมธอดของคลาสนั้น (หรือสมาชิกอื่น ๆ ) ในการเรียกตัวprivateสร้างของคลาส สิ่งนี้ไม่ถือสำหรับตัวสร้างที่ถูกลบ
ทำไมต้องลบตัวสร้างอย่างชัดเจน
อีกเหตุผลหนึ่ง:
ฉันใช้deleteเมื่อต้องการรับรองว่าคลาสถูกเรียกด้วยตัวเริ่มต้น ฉันถือว่าเป็นวิธีที่ดีมากในการบรรลุสิ่งนี้โดยไม่ต้องตรวจสอบรันไทม์
คอมไพเลอร์ C ++ จะตรวจสอบให้คุณ
class Foo
{
public:
Foo() = delete;
Foo(int bar) : m_bar(bar) {};
private:
int m_bar;
}
รหัสนี้ - ง่ายมากทำให้มั่นใจได้ว่าไม่มีการสร้างอินสแตนซ์เช่นนี้:Foo foo;
Fooมีตัวสร้างจำนวนมากไม่ใช่แค่ค่าดีฟอลต์ก็Foo foo;จะทำให้เกิดข้อผิดพลาดอีกต่อไปในการแสดงรายการคอนสตรัคเตอร์ที่กำหนดโดยนัยป้องกันและแบบส่วนตัวทั้งหมดที่ไม่สามารถจับคู่ได้
ฉันได้พบกับ ctors เริ่มต้นที่ประกาศเป็น 'ลบ' ในซอร์สโค้ดของ LLVM (ใน AlignOf.h เป็นต้น) เทมเพลตคลาสที่เกี่ยวข้องมักจะอยู่ในเนมสเปซพิเศษที่เรียกว่า 'llvm :: detail' จุดประสงค์ทั้งหมดที่ฉันคิดคือพวกเขาถือว่าคลาสนั้นเป็นคลาสผู้ช่วยเหลือเท่านั้น พวกเขาไม่เคยตั้งใจที่จะยกตัวอย่างพวกเขา เท่านั้นที่จะใช้ภายในบริบทของเทมเพลตคลาสอื่น ๆ ด้วยเทคนิคการเขียนโปรแกรมเมตาโปรแกรมที่ทำงานในเวลาคอมไพล์
เช่น. มีเทมเพลตคลาส AlignmentCalcImpl ซึ่งใช้เฉพาะในเทมเพลตคลาสอื่นที่เรียกว่า AlignOf เป็นพารามิเตอร์สำหรับตัวดำเนินการ sizeof (.) นิพจน์นั้นสามารถประเมินได้ในเวลาคอมไพล์ และไม่จำเป็นต้องสร้างอินสแตนซ์เทมเพลต -> ดังนั้นทำไมไม่ประกาศลบ ctor เริ่มต้นเพื่อแสดงความตั้งใจนี้
แต่มันเป็นเพียงข้อสันนิษฐานของฉัน
= defaultชั้นเรียนไม่สามารถใช้งานได้และฉันชอบเห็นการใช้ฟังก์ชันที่ถูกลบเป็นการส่วนตัว over Function เป็นแบบส่วนตัว ในอดีตระบุอย่างชัดเจนว่า "สิ่งนี้ไม่ได้มีไว้สำหรับใช้" หากมีสิ่งใดออกมาแสดงว่าคลาสที่ไม่สามารถใช้งานได้จริงจะทำให้เกิดความแตกต่างทางความหมาย