ตัวลบแบบกำหนดเองและฟังก์ชันสร้าง
ใช้ std::make_unique, std::make_shared และตัวลบแบบกำหนดเองกับทรัพยากรที่ไม่ใช่หน่วยความจำ
ตัวลบแบบกำหนดเองและฟังก์ชันสร้าง เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องใช้ตัวลบแบบกำหนดเอง
ทรัพยากรไม่ได้ถูกคืนด้วย delete ทุกชนิด ตัวจัดการไฟล์ ซ็อกเก็ต ทรัพยากรเฉพาะของ OS และอาร์เรย์ ล้วนต้องใช้ฟังก์ชันทำความสะอาดที่แตกต่างกัน
ตัวลบเริ่มต้นสำหรับ unique_ptr
โดยค่าเริ่มต้น unique_ptr<T> จะใช้ delete สำหรับอาร์เรย์ ให้ใช้ unique_ptr<T[]> ซึ่งจะเรียก delete[]
การระบุตัวลบแบบกำหนดเอง
ส่งสิ่งที่เรียกใช้ได้เป็นอาร์กิวเมนต์แม่แบบตัวที่สอง ตัวลบจะได้รับพอยน์เตอร์ดิบและคืนหน่วยความจำอย่างเหมาะสม
auto closer = [](FILE* f) { if (f) std::fclose(f); };
std::unique_ptr<FILE, decltype(closer)> file(
std::fopen("data.txt", "r"), closer);ตัวลบสำหรับ shared_ptr
shared_ptr จัดเก็บตัวลบไว้ในบล็อกควบคุม ชนิดของตัวลบจะถูกลบออกจากชนิด ดังนั้นชนิดของ shared_ptr เองจึงไม่เปลี่ยนแปลง
std::shared_ptr<FILE> file(
std::fopen("data.txt", "r"),
[](FILE* f) { if (f) std::fclose(f); }
);กรณีการใช้งานตัวลบแบบกำหนดเองที่พบบ่อย
ตัวอย่างจากการใช้งานจริง:
- ตัวจัดการของไลบรารี C (FILE*, sqlite3*, ตัวจัดการ curl)
- ทรัพยากรของ OS (HANDLE บน Windows, fd บน Unix)
- พูลหน่วยความจำแบบกำหนดเอง
- ออบเจ็กต์ภายนอกที่นับการอ้างอิง
std::make_unique (C++14)
วิธีที่แนะนำสำหรับสร้าง unique_ptr วิธีนี้ส่งต่ออาร์กิวเมนต์ไปยังตัวสร้างและหลีกเลี่ยงการใช้ new ดิบ
auto p = std::make_unique<Widget>(arg1, arg2);เหตุใดจึงต้องใช้ make_unique
มีประโยชน์สามประการ:
- ความปลอดภัยต่อข้อยกเว้น — ไม่มี
newดิบในโค้ดของผู้ใช้ - ไม่ต้องพิมพ์ชื่อชนิดซ้ำสองครั้ง
- ไม่สามารถส่งพอยน์เตอร์ดิบให้กับ unique_ptr สองตัวโดยไม่ตั้งใจ
std::make_shared
สำหรับ shared_ptr แล้ว make_shared จะจัดสรรบล็อกควบคุมและออบเจ็กต์ในการจัดสรรบนฮีปครั้งเดียว จึงเร็วกว่าการจัดสรรแยกกัน
auto p = std::make_shared<Widget>(arg1, arg2);เมื่อ make_shared มีข้อเสีย
การจัดสรรครั้งเดียวหมายความว่าหน่วยความจำของออบเจ็กต์จะถูกคืนก็ต่อเมื่อ weak_ptr ทั้งหมดถูกทำลายไปแล้วด้วย หาก weak_ptr ของคุณมีอายุยืนยาวกว่า shared_ptr ให้เลือกใช้การสร้างแบบสองขั้นตอน
การใช้ตัวลบแบบกำหนดเองร่วมกับ make
make_unique และ make_shared ไม่รับตัวลบแบบกำหนดเองโดยตรง ในกรณีนั้นให้สร้างพอยน์เตอร์อัจฉริยะด้วยตนเอง
// make_shared cannot take a deleter
std::shared_ptr<FILE> file(
std::fopen("data.txt", "r"),
[](FILE* f) { if (f) std::fclose(f); }
);ข้อควรระวัง: ชนิดของแลมบ์ดาในอาร์กิวเมนต์แม่แบบ
แลมบ์ดาแต่ละตัวมีชนิดเฉพาะตัว สำหรับ unique_ptr ให้ใช้ decltype(my_deleter) เมื่อประกาศ หรือใช้ฟังก์ชันที่มีชื่อหรือพอยน์เตอร์ฟังก์ชันเพื่อให้ชนิดต่าง ๆ เรียบง่าย
ตรวจสอบความเข้าใจ
ฟังก์ชันโรงงานใดทำให้คุณสามารถจัดสรร std::shared_ptr และบล็อกควบคุมในการจัดสรรบนฮีปครั้งเดียว
สรุปทบทวน
ใช้ make_unique และ make_shared สำหรับกรณีทั่วไป เมื่อทรัพยากรต้องการการจัดการมากกว่า delete ให้ระบุตัวลบแบบกำหนดเอง (แลมบ์ดาหรือฟังก์ชัน) เช่น ตัวจัดการไฟล์ ออบเจ็กต์ของ OS หรือการทำความสะอาดของไลบรารี C
เรียนรู้ C++ ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 51
- บทเรียน
- 203
คำถามที่พบบ่อย
บทเรียน “ตัวลบแบบกำหนดเองและฟังก์ชันสร้าง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ตัวลบแบบกำหนดเองและฟังก์ชันสร้าง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ตัวลบแบบกำหนดเองและฟังก์ชันสร้าง”
ใช้ std::make_unique, std::make_shared และตัวลบแบบกำหนดเองกับทรัพยากรที่ไม่ใช่หน่วยความจำ คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “ตัวลบแบบกำหนดเองและฟังก์ชันสร้าง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- เหตุใดพอยน์เตอร์อัจฉริยะจึงมาแทน new และ delete แบบดิบ
- unique_ptr และการครอบครองแต่เพียงผู้เดียว
- shared_ptr และ weak_ptr กับการครอบครองร่วมกัน
- ตัวลบแบบกำหนดเองและฟังก์ชันสร้าง