C ++ 03
std::auto_ptr
- อาจเป็นหนึ่งในต้นฉบับที่ได้รับความทุกข์ทรมานจากโรคร่างแรกเท่านั้นที่มีสถานที่เก็บขยะที่ จำกัด ข้อเสียประการแรกคือการเรียกร้องdelete
ให้ทำลายทำให้ไม่สามารถยอมรับได้ในการถืออาร์เรย์วัตถุที่จัดสรรไว้ ( new[]
) เป็นเจ้าของตัวชี้ดังนั้นตัวชี้อัตโนมัติสองตัวไม่ควรมีวัตถุเดียวกัน การมอบหมายจะโอนความเป็นเจ้าของและรีเซ็ตตัวชี้อัตโนมัติrvalueเป็นตัวชี้ค่าว่าง ซึ่งอาจนำไปสู่ข้อเสียเปรียบที่เลวร้ายที่สุด ไม่สามารถใช้ภายในคอนเทนเนอร์ STL ได้เนื่องจากไม่สามารถคัดลอกข้างต้นได้ ขั้นสุดท้ายสำหรับกรณีการใช้งานคือพวกเขามีกำหนดที่จะเลิกใช้งานในมาตรฐานถัดไปของ C ++
std::auto_ptr_ref
- นี่ไม่ใช่ตัวชี้อัจฉริยะ แต่เป็นรายละเอียดการออกแบบที่ใช้ร่วมกับstd::auto_ptr
เพื่ออนุญาตให้คัดลอกและมอบหมายในบางสถานการณ์ โดยเฉพาะอย่างยิ่งมันสามารถใช้เพื่อแปลง non-const std::auto_ptr
เป็นlvalueโดยใช้เคล็ดลับ Colvin-Gibbons หรือที่เรียกว่าตัวสร้างการย้ายเพื่อโอนความเป็นเจ้าของ
ในทางตรงกันข้ามอาจstd::auto_ptr
ไม่ได้มีไว้เพื่อใช้เป็นตัวชี้อัจฉริยะสำหรับการเก็บขยะอัตโนมัติ ความเข้าใจและสมมติฐานที่ จำกัด ของฉันส่วนใหญ่อิงตามการใช้ auto_ptr อย่างมีประสิทธิภาพของ Herb Sutterและฉันใช้มันเป็นประจำแม้ว่าจะไม่ได้ใช้วิธีที่เหมาะสมที่สุดเสมอไป
C ++ 11
std::unique_ptr
- นี่คือเพื่อนของเราที่จะเข้ามาแทนที่std::auto_ptr
ซึ่งจะค่อนข้างคล้ายกันยกเว้นการปรับปรุงที่สำคัญเพื่อแก้ไขจุดอ่อนของstd::auto_ptr
การทำงานกับอาร์เรย์การป้องกันค่าlvalueผ่านตัวสร้างสำเนาส่วนตัวสามารถใช้งานได้กับคอนเทนเนอร์ STL และอัลกอริทึมเป็นต้นเนื่องจากประสิทธิภาพเหนือศีรษะ และหน่วยความจำมี จำกัด นี่เป็นตัวเลือกที่เหมาะสำหรับการแทนที่หรืออาจอธิบายได้อย่างเหมาะสมกว่าว่าเป็นเจ้าของตัวชี้ดิบ ในฐานะที่เป็น "พิเศษ" std::auto_ptr
หมายถึงมีเพียงหนึ่งเจ้าของตัวชี้เช่นเดียวกับก่อนหน้านี้
std::shared_ptr
- ฉันเชื่อว่านี่เป็นไปตาม TR1 และได้boost::shared_ptr
รับการปรับปรุงให้รวมการใช้นามแฝงและเลขคณิตของตัวชี้ด้วย ในระยะสั้นมันจะรวมการอ้างอิงตัวชี้อัจฉริยะที่นับรอบวัตถุที่จัดสรรแบบไดนามิก เนื่องจาก "ใช้ร่วมกัน" หมายความว่าตัวชี้สามารถเป็นเจ้าของได้โดยตัวชี้ที่ใช้ร่วมกันมากกว่าหนึ่งตัวเมื่อการอ้างอิงสุดท้ายของตัวชี้ที่ใช้ร่วมกันล่าสุดอยู่นอกขอบเขตวัตถุจะถูกลบอย่างเหมาะสม สิ่งเหล่านี้ยังปลอดภัยต่อเธรดและสามารถรองรับประเภทที่ไม่สมบูรณ์ได้ในกรณีส่วนใหญ่ std::make_shared
สามารถใช้เพื่อสร้างการstd::shared_ptr
จัดสรรฮีปอย่างมีประสิทธิภาพโดยใช้ตัวจัดสรรเริ่มต้น
std::weak_ptr
- ในทำนองเดียวกันตาม TR1 และboost::weak_ptr
. นี่คือการอ้างอิงถึงวัตถุที่เป็นเจ้าของstd::shared_ptr
และดังนั้นจะไม่ป้องกันการลบวัตถุหากstd::shared_ptr
จำนวนการอ้างอิงลดลงเหลือศูนย์ ในการเข้าถึงตัวชี้ดิบก่อนอื่นคุณจะต้องเข้าถึงstd::shared_ptr
โดยการโทรlock
ซึ่งจะส่งคืนค่าว่างstd::shared_ptr
หากตัวชี้ที่เป็นเจ้าของหมดอายุและถูกทำลายไปแล้ว สิ่งนี้มีประโยชน์เป็นหลักในการหลีกเลี่ยงการนับการอ้างอิงที่แขวนไม่แน่นอนเมื่อใช้ตัวชี้อัจฉริยะหลายตัว
การส่งเสริม
boost::shared_ptr
- อาจเป็นวิธีที่ง่ายที่สุดที่จะใช้ในสถานการณ์ที่แตกต่างกันมากที่สุด (STL, PIMPL, RAII ฯลฯ ) ซึ่งเป็นตัวชี้อัจฉริยะที่มีการอ้างอิงที่ใช้ร่วมกัน ฉันได้ยินคำบ่นเล็กน้อยเกี่ยวกับประสิทธิภาพและค่าใช้จ่ายในบางสถานการณ์ แต่ฉันคงต้องเพิกเฉยต่อพวกเขาเพราะฉันจำไม่ได้ว่าข้อโต้แย้งคืออะไร เห็นได้ชัดว่ามันเป็นที่นิยมมากพอที่จะกลายเป็นวัตถุ C ++ มาตรฐานที่รอดำเนินการและไม่มีข้อบกพร่องเกี่ยวกับบรรทัดฐานเกี่ยวกับตัวชี้อัจฉริยะที่อยู่ในใจ
boost::weak_ptr
- เช่นเดียวกับคำอธิบายก่อนหน้านี้std::weak_ptr
ตามการใช้งานนี้อนุญาตให้ใช้การอ้างอิงที่ไม่ใช่ของเจ้าของไปยังไฟล์boost::shared_ptr
. คุณไม่ต้องแปลกใจที่lock()
จะเรียกใช้ตัวชี้ที่ใช้ร่วมกัน "ที่แข็งแกร่ง" และต้องตรวจสอบให้แน่ใจว่าถูกต้องเนื่องจากอาจถูกทำลายไปแล้ว อย่าลืมจัดเก็บตัวชี้ที่ใช้ร่วมกันที่ส่งคืนและปล่อยให้อยู่นอกขอบเขตทันทีที่คุณดำเนินการเสร็จมิฉะนั้นคุณจะกลับไปที่ปัญหาการอ้างอิงแบบวนซ้ำซึ่งการนับการอ้างอิงของคุณจะค้างและวัตถุจะไม่ถูกทำลาย
boost::scoped_ptr
- นี่คือคลาสตัวชี้อัจฉริยะแบบธรรมดาที่มีค่าใช้จ่ายเพียงเล็กน้อยซึ่งอาจได้รับการออกแบบมาเพื่อเป็นทางเลือกที่มีประสิทธิภาพดีกว่าboost::shared_ptr
เมื่อใช้งานได้ เทียบได้กับstd::auto_ptr
โดยเฉพาะอย่างยิ่งในความจริงที่ว่าไม่สามารถใช้เป็นองค์ประกอบของคอนเทนเนอร์ STL ได้อย่างปลอดภัยหรือมีตัวชี้หลายตัวไปยังวัตถุเดียวกัน
boost::intrusive_ptr
- ฉันไม่เคยใช้สิ่งนี้ แต่จากความเข้าใจของฉันมันถูกออกแบบมาเพื่อใช้เมื่อสร้างคลาสที่เข้ากันได้กับตัวชี้อัจฉริยะของคุณเอง คุณต้องใช้การนับการอ้างอิงด้วยตัวคุณเองคุณจะต้องใช้วิธีการบางอย่างหากคุณต้องการให้คลาสของคุณเป็นแบบทั่วไปนอกจากนี้คุณต้องใช้ความปลอดภัยของเธรดของคุณเอง ในทางบวกสิ่งนี้อาจช่วยให้คุณเลือกและเลือกได้ว่าต้องการ "ความฉลาด" มากหรือน้อยเพียงใด intrusive_ptr
โดยทั่วไปจะมีประสิทธิภาพมากกว่าshared_ptr
เนื่องจากช่วยให้คุณมีการจัดสรรฮีปเดียวต่อออบเจ็กต์ (ขอบคุณ Arvid)
boost::shared_array
- นี่คือboost::shared_ptr
สำหรับอาร์เรย์ โดยทั่วไปnew []
, operator[]
และแน่นอนdelete []
จะอบใน. นี้สามารถนำมาใช้ในภาชนะ STL และเท่าที่ผมรู้ว่าไม่ทุกอย่างboost:shared_ptr
ไม่แม้ว่าคุณจะไม่สามารถใช้boost::weak_ptr
กับสิ่งเหล่านี้ อย่างไรก็ตามคุณสามารถใช้ a boost::shared_ptr<std::vector<>>
สำหรับฟังก์ชันการทำงานที่คล้ายกันและเพื่อฟื้นความสามารถในการใช้boost::weak_ptr
อ้างอิงได้
boost::scoped_array
- นี่คือboost::scoped_ptr
สำหรับอาร์เรย์ เช่นเดียวกับboost::shared_array
ความดีงามของอาร์เรย์ที่จำเป็นทั้งหมดถูกอบไว้อันนี้ไม่สามารถคัดลอกได้จึงไม่สามารถใช้ในคอนเทนเนอร์ STL ได้ ฉันพบเกือบทุกที่ที่คุณพบว่าตัวเองต้องการใช้สิ่งนี้คุณอาจจะstd::vector
ใช้ได้ ฉันไม่เคยพิจารณาว่าอันไหนเร็วกว่าหรือมีค่าโสหุ้ยน้อย แต่อาร์เรย์ที่กำหนดขอบเขตนี้ดูเหมือนจะเกี่ยวข้องน้อยกว่าเวกเตอร์ STL มาก เมื่อคุณต้องการเก็บการจัดสรรบนสแต็กให้พิจารณาboost::array
แทน
Qt
QPointer
- แนะนำใน Qt 4.0 นี่คือสมาร์ทพอยน์เตอร์ที่ "อ่อนแอ" ซึ่งใช้ได้เฉพาะกับQObject
คลาสที่ได้รับเท่านั้นซึ่งในเฟรมเวิร์ก Qt นั้นแทบจะทุกอย่างดังนั้นจึงไม่ใช่ข้อ จำกัด จริงๆ อย่างไรก็ตามมีข้อ จำกัด คือไม่มีตัวชี้ที่ "แข็งแรง" และแม้ว่าคุณจะตรวจสอบได้ว่าวัตถุที่อยู่ข้างใต้นั้นใช้ได้หรือisNull()
ไม่ แต่คุณพบว่าวัตถุของคุณถูกทำลายทันทีหลังจากที่คุณผ่านการตรวจสอบนั้นโดยเฉพาะในสภาพแวดล้อมแบบมัลติเธรด Qt ผู้คนคิดว่าสิ่งนี้เลิกใช้แล้วฉันเชื่อว่า
QSharedDataPointer
- นี่คือ "ความเชื่อ" ชี้สมาร์ทที่อาจเทียบเคียงได้กับboost::intrusive_ptr
แม้ว่ามันจะมีบางส่วนที่สร้างขึ้นในหัวข้อความปลอดภัย แต่ก็ไม่ต้องการให้คุณรวมถึงวิธีการตรวจนับการอ้างอิง ( ref
และderef
) ซึ่งคุณสามารถทำได้ด้วย QSharedData
subclassing เช่นเดียวกับ Qt ส่วนใหญ่วัตถุจะถูกใช้อย่างดีที่สุดผ่านการสืบทอดที่กว้างขวางและการแบ่งคลาสย่อยทุกอย่างดูเหมือนจะเป็นการออกแบบที่ตั้งใจไว้
QExplicitlySharedDataPointer
- ที่คล้ายกันมากที่จะยกเว้นก็ไม่ได้เรียกร้องโดยปริยายQSharedDataPointer
detach()
ฉันจะเรียกเวอร์ชัน 2.0 นี้QSharedDataPointer
ว่าการควบคุมที่เพิ่มขึ้นเล็กน้อยว่าเมื่อใดที่จะแยกออกหลังจากจำนวนอ้างอิงลดลงเป็นศูนย์โดยเฉพาะอย่างยิ่งไม่คุ้มค่ากับวัตถุใหม่ทั้งหมด
QSharedPointer
- การนับการอ้างอิงอะตอม, เธรดปลอดภัย, ตัวชี้ที่แชร์ได้, การลบแบบกำหนดเอง (รองรับอาร์เรย์) ดูเหมือนทุกอย่างที่ตัวชี้อัจฉริยะควรจะเป็น นี่คือสิ่งที่ฉันใช้เป็นสมาร์ทพอยน์เตอร์ใน Qt เป็นหลักและฉันพบว่ามันเทียบได้กับboost:shared_ptr
แม้ว่าอาจจะมีค่าใช้จ่ายมากกว่าอย่างมีนัยสำคัญเช่นหลายวัตถุใน Qt
QWeakPointer
- คุณรู้สึกถึงรูปแบบที่เกิดซ้ำหรือไม่? เช่นเดียวกับstd::weak_ptr
และboost::weak_ptr
ใช้ร่วมกับQSharedPointer
เมื่อคุณต้องการการอ้างอิงระหว่างตัวชี้อัจฉริยะสองตัวที่อาจทำให้วัตถุของคุณไม่ถูกลบ
QScopedPointer
- ชื่อนี้ควรดูคุ้นเคยและอันที่จริงแล้วนั้นมีพื้นฐานมาboost::scoped_ptr
จากตัวชี้ที่ใช้ร่วมกันและจุดอ่อนของ Qt มันทำหน้าที่ในการจัดหาตัวชี้อัจฉริยะสำหรับเจ้าของคนเดียวโดยไม่มีค่าใช้จ่ายQSharedPointer
ซึ่งทำให้เหมาะสำหรับความเข้ากันได้มากขึ้นรหัสปลอดภัยข้อยกเว้นและทุกสิ่งที่คุณอาจใช้std::auto_ptr
หรือboost::scoped_ptr
สำหรับ