ด้วยภาษา C ++ 17 , shared_ptrสามารถนำมาใช้ในการจัดการอาร์เรย์จัดสรร shared_ptrอาร์กิวเมนต์แม่แบบในกรณีนี้จะต้องเป็นหรือT[N] T[]ดังนั้นคุณอาจเขียน
shared_ptr<int[]> sp(new int[10]);
จาก n4659, [util.smartptr.shared.const]
template<class Y> explicit shared_ptr(Y* p);
ต้องการ: Yจะเป็นประเภทที่สมบูรณ์ การแสดงออกdelete[] pเมื่อTเป็นประเภทอาร์เรย์หรือdelete pเมื่อTไม่ได้เป็นประเภทอาร์เรย์จะต้องมีพฤติกรรมที่กำหนดไว้อย่างดีและจะไม่โยนข้อยกเว้น
...
ข้อสังเกต:เมื่อTเป็นประเภทอาร์เรย์คอนสตรัคนี้จะได้มีส่วนร่วมในการแก้ปัญหาเกินเว้นแต่การแสดงออกdelete[] pเป็นรูปแบบที่ดีและทั้งTเป็นU[N]และY(*)[N]เป็นแปลงสภาพให้แก่T*หรือTเป็น
U[]และเป็นแปลงสภาพให้แก่Y(*)[] T*...
เพื่อรองรับสิ่งนี้ประเภทสมาชิกelement_typeจะถูกกำหนดเป็น
using element_type = remove_extent_t<T>;
องค์ประกอบอาร์เรย์สามารถเข้าถึงได้โดยใช้ operator[]
element_type& operator[](ptrdiff_t i) const;
get() != 0 && i >= 0ต้องใช้: ถ้าTเป็นU[N], i < N. ...
ข้อสังเกต:เมื่อTไม่ได้เป็นประเภทอาเรย์มันจะไม่ได้ระบุว่าฟังก์ชั่นสมาชิกนี้จะมีการประกาศ ถ้ามันถูกประกาศมันจะไม่ระบุว่าประเภทการคืนของมันคืออะไรยกเว้นว่าการประกาศ (แม้ว่าไม่จำเป็นต้องนิยาม) ของฟังก์ชั่นจะต้องมีรูปแบบที่ดี
ก่อนที่จะมี C ++ 17 , shared_ptrอาจจะไม่ได้ถูกนำมาใช้ในการจัดการอาร์เรย์จัดสรร โดยค่าเริ่มต้นshared_ptrจะเรียกdeleteวัตถุที่มีการจัดการเมื่อไม่มีการอ้างอิงอีกต่อไป อย่างไรก็ตามเมื่อคุณจัดสรรโดยใช้new[]คุณต้องโทรdelete[]และไม่deleteให้เป็นอิสระจากทรัพยากร
เพื่อที่จะใช้shared_ptrกับอาร์เรย์ได้อย่างถูกต้องคุณต้องกำหนด deleter ที่กำหนดเอง
template< typename T >
struct array_deleter
{
void operator ()( T const * p)
{
delete[] p;
}
};
สร้าง shared_ptr ดังนี้:
std::shared_ptr<int> sp(new int[10], array_deleter<int>());
ตอนนี้shared_ptrจะเรียกอย่างถูกต้องdelete[]เมื่อทำลายวัตถุที่มีการจัดการ
deleter ที่กำหนดเองด้านบนอาจถูกแทนที่ด้วย
std::default_deleteเชี่ยวชาญบางส่วนสำหรับประเภทอาร์เรย์
std::shared_ptr<int> sp(new int[10], std::default_delete<int[]>());
การแสดงออกแลมบ์ดา
std::shared_ptr<int> sp(new int[10], [](int *p) { delete[] p; });
นอกจากนี้หากคุณต้องการใช้งานร่วมกันจริงกับวัตถุที่มีการจัดการ a unique_ptrเหมาะกว่าสำหรับงานนี้เนื่องจากมีความเชี่ยวชาญบางส่วนสำหรับประเภทอาร์เรย์
std::unique_ptr<int[]> up(new int[10]); // this will correctly call delete[]
การเปลี่ยนแปลงที่แนะนำโดย C ++ Extensions สำหรับ Library Fundamentals
pre-C ++ 17 ทางเลือกอื่น ๆ ที่ระบุไว้ข้างต้นได้รับการจัดทำโดยข้อกำหนดพื้นฐานทางเทคนิคของLibrary Fundamentalsซึ่งเพิ่มขึ้นshared_ptrเพื่อให้สามารถทำงานนอกกรอบสำหรับกรณีต่างๆเมื่อเป็นเจ้าของอาร์เรย์ของวัตถุ ร่างปัจจุบันของshared_ptrการเปลี่ยนแปลงที่กำหนดไว้สำหรับการ TS นี้สามารถพบได้ในN4082 การเปลี่ยนแปลงเหล่านี้จะสามารถเข้าถึงได้ผ่านstd::experimentalnamespace และรวมอยู่ใน<experimental/memory>ส่วนหัว การเปลี่ยนแปลงที่เกี่ยวข้องบางประการเพื่อสนับสนุนshared_ptrอาร์เรย์คือ:
- คำจำกัดความของการelement_typeเปลี่ยนแปลงประเภทสมาชิก
typedef T element_type;
typedef typename remove_extent<T>::type element_type;
- operator[]กำลังเพิ่มสมาชิก
element_type& operator[](ptrdiff_t i) const noexcept;
- ไม่เหมือนกับunique_ptrความเชี่ยวชาญเฉพาะบางส่วนสำหรับอาร์เรย์ทั้งสองshared_ptr<T[]>และshared_ptr<T[N]>จะใช้ได้และทั้งคู่จะส่งผลให้delete[]ถูกเรียกใช้บนอาร์เรย์ของวัตถุที่มีการจัดการ
template<class Y> explicit shared_ptr(Y* p);
ต้องการ : Yจะเป็นประเภทที่สมบูรณ์ การแสดงออกdelete[] pเมื่อTเป็นประเภทอาร์เรย์หรือdelete pเมื่อTไม่ได้เป็นประเภทอาร์เรย์จะต้องมีรูปแบบที่ดีจะต้องมีพฤติกรรมที่กำหนดไว้อย่างดีและจะไม่โยนข้อยกเว้น เมื่อTเป็นU[N], Y(*)[N]จะต้องแปลงสภาพให้แก่T*; เมื่อTเป็นU[], Y(*)[]จะต้องแปลงสภาพให้แก่T*; มิฉะนั้นจะต้องแปลงสภาพให้แก่Y*T*
std::vectorคุณยังอาจพิจารณาเพียงแค่ใช้ คุณจะต้องระมัดระวังในการส่งอาเรย์โดยใช้การอ้างอิงเพื่อที่คุณจะไม่ได้ทำสำเนา ไวยากรณ์สำหรับการเข้าถึงข้อมูลนั้นสะอาดกว่า shared_ptr และการปรับขนาดมันง่ายมาก และคุณจะได้รับความดี STL ทั้งหมดที่คุณต้องการ