เหตุใด C ++ ไลบรารีและกรอบงานไม่เคยใช้พอยน์เตอร์อัจฉริยะ


156

ฉันอ่านบทความสองสามฉบับที่ไม่ควรใช้ตัวชี้แบบดิบ แต่ควรห่อด้วยพอยน์เตอร์พอยน์เตอร์เสมอไม่ว่าจะเป็นพอยน์เตอร์ที่กำหนดขอบเขตหรือแชร์

อย่างไรก็ตามฉันสังเกตเห็นว่าเฟรมเวิร์กอย่าง Qt, wxWidgets และไลบรารี่อย่าง Boost ไม่เคยกลับมาหรือคาดหวังว่าจะมีพอยน์เตอร์พอยน์เตอร์ราวกับว่าพวกเขาไม่ได้ใช้เลย พวกเขากลับมาหรือคาดหวังตัวชี้ดิบ มีเหตุผลอะไรบ้าง? ฉันควรอยู่ห่างจากตัวชี้สมาร์ทเมื่อฉันเขียน API สาธารณะและทำไม

เพียงแค่สงสัยว่าเหตุใดจึงแนะนำสมาร์ทพอยน์เตอร์เมื่อโครงการสำคัญหลายโครงการดูเหมือนจะหลีกเลี่ยง


22
ห้องสมุดเหล่านี้ทั้งหมดที่คุณเพิ่งตั้งชื่อได้เริ่มมาหลายปีแล้ว พอยน์เตอร์อัจฉริยะกลายเป็นมาตรฐานอย่างแท้จริงใน C ++ 11 เท่านั้น
chrisaycock

22
ตัวชี้สมาร์ทมีค่าใช้จ่าย (การนับการอ้างอิง ฯลฯ ) ซึ่งอาจสำคัญ - ในระบบฝัง / เวลาจริงเช่น IMHO - พอยน์เตอร์อัจฉริยะใช้สำหรับโปรแกรมเมอร์ที่ขี้เกียจ API จำนวนมากยังเป็นตัวหารร่วมที่ต่ำที่สุด ฉันรู้สึกว่ามีไฟลุกโชนรอบเท้าขณะพิมพ์!
Ed Heal

93
@ EdHeal: เหตุผลที่ทำให้คุณรู้สึกว่าไฟลุกโชนอยู่รอบ ๆ เท้าของคุณก็เพราะคุณผิดทุกประการ ตัวอย่างเช่นมีค่าใช้จ่ายในunique_ptrอะไร ไม่มี แต่อย่างใด. Qt / WxWidgets ตั้งเป้าหมายไว้ที่ระบบฝังตัวหรือตามเวลาจริงหรือไม่? ไม่มันมีไว้สำหรับ Windows / Mac / Unix บนเดสก์ท็อปเป็นอย่างมาก พอยน์เตอร์อัจฉริยะใช้สำหรับโปรแกรมเมอร์ที่ต้องการแก้ไขให้ถูกต้อง
ลูกสุนัข

24
โทรศัพท์มือถือกำลังเรียกใช้จาวาจริงๆ
R. Martinho Fernandes

12
ตัวชี้สมาร์ทมาตรฐานอย่างแท้จริงใน C ++ 11 เท่านั้น? อะไร??? สิ่งเหล่านี้ถูกใช้มานานกว่า 20 ปี
Kaz

คำตอบ:


124

นอกเหนือจากความจริงที่ว่าห้องสมุดหลายแห่งถูกเขียนขึ้นก่อนที่จะมีพอยน์เตอร์อัจฉริยะมาตรฐานเหตุผลที่ใหญ่ที่สุดน่าจะเป็นเพราะขาด C ++ Application Binary Interface (ABI) มาตรฐาน

หากคุณกำลังเขียนห้องสมุดเฉพาะส่วนหัวคุณสามารถส่งต่อพอยน์เตอร์อัจฉริยะและคอนเทนเนอร์มาตรฐานไปยังเนื้อหาในใจของคุณ แหล่งที่มาของมันมีให้สำหรับห้องสมุดของคุณในเวลารวบรวมดังนั้นคุณต้องพึ่งพาความเสถียรของอินเทอร์เฟซของพวกเขาเพียงอย่างเดียว

แต่เนื่องจากการขาด ABI มาตรฐานโดยทั่วไปคุณไม่สามารถผ่านวัตถุเหล่านี้อย่างปลอดภัยข้ามขอบเขตของโมดูล GCC shared_ptrอาจจะแตกต่างจาก MSVC ซึ่งก็สามารถแตกต่างจากอินเทลshared_ptr shared_ptrแม้ว่าจะมีคอมไพเลอร์เดียวกันแต่คลาสเหล่านี้ไม่ได้รับประกันว่าจะเข้ากันได้กับไบนารีระหว่างเวอร์ชัน

บรรทัดล่างคือถ้าคุณต้องการแจกจ่ายไลบรารี่รุ่นที่สร้างไว้ล่วงหน้าของคุณคุณต้องมี ABI มาตรฐานที่ต้องใช้ C ไม่มี แต่ผู้จำหน่ายคอมไพเลอร์ดีมากเกี่ยวกับการทำงานร่วมกันระหว่างไลบรารี C สำหรับแพลตฟอร์มที่กำหนด - มีมาตรฐานตามความเป็นจริง

สถานการณ์ไม่ดีสำหรับ C ++ คอมไพเลอร์ส่วนบุคคลสามารถจัดการการทำงานร่วมกันระหว่างไบนารีของตัวเองดังนั้นคุณมีตัวเลือกในการกระจายรุ่นสำหรับคอมไพเลอร์ที่รองรับทุกคนมักจะ GCC และ MSVC แต่ด้วยเหตุนี้ไลบรารีส่วนใหญ่จึงส่งออกอินเทอร์เฟซ C และนั่นหมายถึงตัวชี้แบบดิบ

อย่างไรก็ตามรหัสที่ไม่ใช่ห้องสมุดควรชอบตัวชี้สมาร์ทมากกว่าวัตถุดิบ


17
ฉันเห็นด้วยกับคุณแม้ผ่าน std :: string อาจเป็นเรื่องเจ็บปวดนี่พูดได้มากมายเกี่ยวกับ C ++ ในฐานะ "ภาษาที่ยอดเยี่ยมสำหรับห้องสมุด"
Ha11owed

8
บรรทัดล่างเป็นเหมือน: ถ้าคุณต้องการกระจายรุ่น prebuild คุณต้องทำสำหรับคอมไพเลอร์ทุกตัวที่คุณต้องการสนับสนุน
josefx

6
@josefx: ใช่นี่เป็นเรื่องน่าเศร้า แต่เป็นความจริงทางเลือกเดียวคือ COM หรืออินเตอร์เฟส C แบบ raw ฉันหวังว่า C ++ comity จะเริ่มกังวลกับปัญหาแบบนี้ ฉันหมายความว่ามันไม่เหมือน C ++ เป็นภาษาใหม่เมื่อ 2 ปีที่แล้ว
ระเบียบหุ่นยนต์

3
ฉันลงคะแนนเพราะนี่ผิด ปัญหา ABI เป็นมากกว่าการจัดการในกรณีส่วนใหญ่ ในขณะที่ใช้งานง่ายแทบจะไม่ ABI ก็ผ่านไม่ได้
ลูกสุนัข

4
@NathanAdams: ซอฟต์แวร์ดังกล่าวน่าประทับใจและมีประโยชน์ แต่มันจัดการกับอาการของปัญหาที่ลึกกว่า: ความหมายของ C ++ ตลอดชีวิตและความเป็นเจ้าของอยู่ระหว่างความยากจนและไม่มีอยู่จริง ข้อบกพร่องฮีปเหล่านั้นจะไม่เกิดขึ้นหากภาษาไม่อนุญาต ดังนั้นตัวชี้สมาร์ทไม่ใช่ยาครอบจักรวาล - พวกเขาพยายามกู้คืนความสูญเสียบางส่วนที่เกิดจากการใช้ C ++ ในตอนแรก
Jon Purdy

40

อาจมีหลายเหตุผล ในการแสดงรายการไม่กี่รายการ:

  1. พอยน์เตอร์อัจฉริยะกลายเป็นส่วนหนึ่งของมาตรฐานเมื่อเร็ว ๆ นี้ จนกระทั่งพวกเขาเป็นส่วนหนึ่งของห้องสมุดอื่น ๆ
  2. การใช้งานหลักคือหลีกเลี่ยงการรั่วไหลของหน่วยความจำ ห้องสมุดหลายแห่งไม่มีการจัดการหน่วยความจำของตนเอง โดยทั่วไปแล้วพวกเขามีสาธารณูปโภคและ API
  3. พวกเขาถูกนำมาใช้เป็นเสื้อคลุมเนื่องจากเป็นจริงวัตถุและไม่ชี้ ซึ่งมีเวลาเพิ่มเติม / พื้นที่ค่าใช้จ่ายเมื่อเทียบกับตัวชี้ดิบ ผู้ใช้ห้องสมุดอาจไม่ต้องการมีค่าใช้จ่ายดังกล่าว

แก้ไข : การใช้ตัวชี้อัจฉริยะเป็นตัวเลือกของนักพัฒนาอย่างสมบูรณ์ มันขึ้นอยู่กับปัจจัยต่าง ๆ

  1. ในระบบที่มีความสำคัญต่อประสิทธิภาพคุณอาจไม่ต้องการใช้พอยน์เตอร์อัจฉริยะที่สร้างค่าใช้จ่าย

  2. โครงการที่ต้องการความเข้ากันได้แบบย้อนหลังคุณอาจไม่ต้องการใช้ตัวชี้สมาร์ทที่มีคุณสมบัติเฉพาะ C ++ 11

Edit2มีสตริงของ downvotes หลายรายการในช่วงเวลา 24 ชั่วโมงเนื่องจากทางด้านล่าง ฉันล้มเหลวที่จะเข้าใจว่าทำไมคำตอบคือ downvoted แม้ว่าด้านล่างเป็นเพียงคำแนะนำเพิ่มเติมและไม่ใช่คำตอบ
อย่างไรก็ตาม C ++ ช่วยให้คุณเปิดตัวเลือกได้เสมอ :) เช่น

template<typename T>
struct Pointer {
#ifdef <Cpp11>
  typedef std::unique_ptr<T> type;
#else
  typedef T* type;
#endif
};

และในรหัสของคุณใช้มันเป็น:

Pointer<int>::type p;

สำหรับผู้ที่กล่าวว่าตัวชี้สมาร์ทและตัวชี้แบบดิบนั้นแตกต่างกันฉันเห็นด้วยกับสิ่งนั้น โค้ดด้านบนเป็นเพียงความคิดที่ว่าใครสามารถเขียนโค้ดที่สามารถใช้แทนกันได้กับ a #defineนี่ไม่ใช่การบังคับ ;

ตัวอย่างเช่นT*จะต้องลบอย่างชัดเจน แต่ตัวชี้สมาร์ทไม่ได้ เราสามารถสร้างเทมเพลตDestroy()เพื่อจัดการกับมันได้

template<typename T>
void Destroy (T* p)
{
  delete p;
}
template<typename T>
void Destroy (std::unique_ptr<T> p)
{
  // do nothing
}

และใช้เป็น:

Destroy(p);

ในทำนองเดียวกันสำหรับตัวชี้ดิบเราสามารถคัดลอกโดยตรงและสำหรับตัวชี้สมาร์ทเราสามารถใช้การดำเนินการพิเศษ

Pointer<X>::type p = new X;
Pointer<X>::type p2(Assign(p));

อยู่ที่ไหนAssign():

template<typename T>
T* Assign (T *p)
{
  return p;
}
template<typename T>
... Assign (SmartPointer<T> &p)
{
  // use move sematics or whateve appropriate
}

14
ในวันที่ 3 พอยน์เตอร์อัจฉริยะบางตัวมีค่าใช้จ่ายด้านเวลา / พื้นที่เพิ่มเติมส่วนที่เหลือไม่รวมถึงstd::auto_ptrส่วนหนึ่งของมาตรฐานมาเป็นเวลานาน (และโปรดทราบฉันชอบstd::auto_ptrเป็นประเภทส่งคืนสำหรับฟังก์ชันที่สร้างวัตถุแม้ว่าจะเป็น เกือบจะไร้ประโยชน์ทุกที่) ใน C ++ 11 std::unique_ptrไม่มีค่าใช้จ่ายเพิ่มเติมจากตัวชี้ธรรมดา
David Rodríguez - dribeas

4
แน่นอน ... มีความสมมาตรที่ดีในการปรากฏตัวunique_ptrและหายไปของauto_ptrรหัสการกำหนดเป้าหมาย C ++ 03 ควรใช้ในภายหลังในขณะที่การกำหนดเป้าหมายรหัส C ++ 11 สามารถใช้ในอดีต ตัวชี้สมาร์ทไม่ได้ shared_ptrมีมาตรฐานจำนวนมากและไม่มีมาตรฐานรวมถึงข้อเสนอมาตรฐานที่ถูกปฏิเสธในฐานะmanaged_ptr
David Rodríguez - dribeas

2
@iammilind นั้นเป็นจุดที่น่าสนใจ แต่สิ่งที่ตลกคือถ้าเราลงเอยด้วยการใช้พอยน์เตอร์สมาร์ทตามที่หลายคนแนะนำเราก็จบด้วยการสร้างโค้ดที่เข้ากันไม่ได้กับไลบรารี่หลัก ๆ แน่นอนว่าเราสามารถห่อ / แกะตัวชี้สมาร์ทได้ตามต้องการ แต่ดูเหมือนจะยุ่งยากมากและจะสร้างรหัสที่ไม่สอดคล้องกัน (บางครั้งเราจัดการกับพอยน์เตอร์พอยน์เตอร์ไม่ได้)
เรน

7
คำสั่งที่ตัวชี้สมาร์ทมี "เวลาเพิ่มเติม / พื้นที่ค่าใช้จ่าย" ค่อนข้างทำให้เข้าใจผิด; ตัวชี้สมาร์ททั้งหมดยกเว้นunique_ptrค่าใช้จ่ายรันไทม์ แต่unique_ptrเป็นค่าที่ใช้บ่อยที่สุด ตัวอย่างโค้ดที่คุณให้นั้นทำให้เข้าใจผิดด้วยunique_ptrและT*เป็นแนวคิดที่แตกต่างอย่างสิ้นเชิง ความจริงที่ว่าคุณอ้างถึงพวกเขาทั้งสองเป็นการtypeให้ความรู้สึกว่าพวกเขาสามารถแลกเปลี่ยนกันได้
void-pointer

12
คุณไม่สามารถพิมพ์ได้เช่นนั้นประเภทเหล่านี้จะไม่เทียบเท่ากัน การพิมพ์ตัวอักษรแบบนี้เป็นการถามปัญหา
อเล็กซ์ B

35

มีสองประเด็นกับตัวชี้สมาร์ท (ก่อน C ++ 11):

  • ไม่ใช่มาตรฐานดังนั้นแต่ละห้องสมุดมีแนวโน้มที่จะบูรณาการของตัวเอง (ปัญหา NIH & การพึ่งพาอาศัยกัน)
  • ค่าใช้จ่ายที่อาจเกิดขึ้น

เริ่มต้นunique_ptrชี้สมาร์ทในการที่จะเป็นค่าใช้จ่ายฟรีเป็น น่าเสียดายที่มันต้องใช้ซีแมนทิกส์การย้าย C ++ 11 ซึ่งเพิ่งปรากฏเมื่อไม่นานมานี้ ตัวชี้สมาร์ทอื่น ๆ ทั้งหมดมีค่าใช้จ่าย ( shared_ptr, intrusive_ptr) หรือมีความหมายน้อยกว่าอุดมคติ ( auto_ptr)

ด้วย C ++ 11 รอบมุมการนำstd::unique_ptrหนึ่งจะถูกล่อลวงให้คิดว่าในที่สุดมันก็จบ ... ฉันไม่ได้มองในแง่ดี

มีคอมไพเลอร์หลักเพียงไม่กี่ตัวเท่านั้นที่ใช้ C ++ 11 ส่วนใหญ่และเฉพาะในเวอร์ชันล่าสุด เราสามารถคาดหวังว่าห้องสมุดหลัก ๆ เช่น QT และ Boost ยินดีที่จะรักษาความเข้ากันได้กับ C ++ 03 ได้ระยะหนึ่งซึ่งค่อนข้างกีดกันการใช้พอยน์เตอร์อัจฉริยะที่ฉลาดและใหม่


12

คุณไม่ควรอยู่ห่างจากตัวชี้สมาร์ทพวกเขามีการใช้งานโดยเฉพาะอย่างยิ่งในแอปพลิเคชันที่คุณต้องผ่านวัตถุ

ไลบรารีมีแนวโน้มที่จะเพียงแค่ส่งคืนค่าหรือเติมวัตถุ พวกเขามักจะไม่มีวัตถุที่จำเป็นต้องใช้ในสถานที่จำนวนมากดังนั้นจึงไม่จำเป็นต้องให้พวกเขาใช้ตัวชี้สมาร์ท (อย่างน้อยไม่ได้อยู่ในอินเทอร์เฟซของพวกเขาพวกเขาอาจใช้ภายใน)

ฉันสามารถยกตัวอย่างเช่นห้องสมุดที่เราทำงานอยู่หลังจากนั้นไม่กี่เดือนของการพัฒนาฉันรู้ว่าเราใช้พอยน์เตอร์พอยน์เตอร์และพอยน์เตอร์อัจฉริยะในชั้นเรียนเพียงไม่กี่ชั้น (3-5% ของชั้นเรียนทั้งหมด)

ผ่านตัวแปรโดยการอ้างอิงนั้นเพียงพอในสถานที่ส่วนใหญ่เราใช้ตัวชี้สมาร์ทเมื่อใดก็ตามที่เรามีวัตถุที่อาจเป็นโมฆะและตัวชี้แบบดิบเมื่อห้องสมุดที่เราใช้บังคับให้เราทำ

แก้ไข (ฉันไม่สามารถแสดงความคิดเห็นเนื่องจากชื่อเสียงของฉัน): การส่งผ่านตัวแปรโดยการอ้างอิงนั้นมีความยืดหยุ่นมาก: ถ้าคุณต้องการให้วัตถุอ่านได้อย่างเดียวคุณสามารถใช้การอ้างอิง const (คุณยังสามารถทำบาง cast cast ที่น่ารังเกียจเพื่อให้สามารถเขียนวัตถุได้ ) แต่คุณจะได้รับการปกป้องสูงสุดเท่าที่จะเป็นไปได้ (เหมือนกับตัวชี้อัจฉริยะ) แต่ฉันเห็นด้วยว่ามันดีกว่าการคืนสิ่งของ


ฉันไม่เห็นด้วยกับคุณ แต่ฉันจะชี้ให้เห็นว่ามีโรงเรียนแห่งความคิดที่เลิกการอ้างอิงตัวแปรในหลายกรณี ฉันยอมรับว่าฉันยึดมั่นในโรงเรียนนั้น ฉันชอบฟังก์ชั่นที่จะไม่แก้ไขข้อโต้แย้งของพวกเขา เท่าที่ฉันรู้การอ้างอิงตัวแปรของ C ++ ไม่ได้ทำอะไรเพื่อป้องกันความผิดพลาดของวัตถุที่พวกเขาอ้างถึงซึ่งเป็นสิ่งที่ตัวชี้สมาร์ทตั้งใจที่จะทำ
บาท

2
คุณมีความตั้งใจ (ที่ฉันสามารถแสดงความคิดเห็น: D)
ระเบียบหุ่นยนต์

9

Qt ได้คิดค้นหลายส่วนของ Standard Library ขึ้นใหม่โดยไม่มีจุดหมายในความพยายามที่จะเป็น Java ฉันเชื่อว่าตอนนี้มันมีพอยน์เตอร์อัจฉริยะของตัวเองแล้ว แต่โดยทั่วไปมันแทบจะไม่ได้เป็นจุดสุดยอดของการออกแบบ wxWidgets เท่าที่ฉันทราบได้รับการออกแบบมานานก่อนที่จะเขียนพอยน์เตอร์อัจฉริยะที่ใช้งานได้

สำหรับ Boost ฉันคาดหวังอย่างเต็มที่ว่าพวกเขาจะใช้พอยน์เตอร์อัจฉริยะตามที่เหมาะสม คุณอาจจะต้องเจาะจงมากขึ้น

นอกจากนี้อย่าลืมว่าตัวชี้สมาร์ทมีอยู่เพื่อบังคับใช้ความเป็นเจ้าของ หาก API ไม่มีซีแมนทิกส์เป็นเจ้าของเหตุใดจึงต้องใช้ตัวชี้สมาร์ท


19
Qt นั้นถูกเขียนขึ้นก่อนหน้าที่การใช้งานส่วนใหญ่จะแพร่หลายอย่างกว้างขวางบนแพลตฟอร์มที่ต้องการใช้ มันมีพอยน์เตอร์ที่ชาญฉลาดมาเป็นเวลานานและใช้มันเพื่อแบ่งปันทรัพยากรโดยปริยายในคลาส Q * เกือบทั้งหมด
rubenvb

6
ห้องสมุด GUI ทุกแห่งสามารถพลิกโฉมวงล้อได้โดยไม่จำเป็น แม้สตริง Qt มีQString, wxWidgets ได้wxString, CStringเอ็มเอฟได้ชื่ออย่างน่ากลัว UTF-8 ไม่std::stringดีพอสำหรับงาน GUI 99% ใช่หรือไม่
ผกผัน

10
@Inverse QString ถูกสร้างขึ้นเมื่อ std :: string ไม่อยู่
MrFox

ตรวจสอบเมื่อ qt ถูกสร้างขึ้นและตัวชี้สมาร์ทที่มีอยู่ในเวลานั้น
Dainius

3

คำถามที่ดี. ฉันไม่รู้บทความเฉพาะที่คุณอ้างถึง แต่ฉันได้อ่านสิ่งที่คล้ายกันเป็นครั้งคราว ความสงสัยของฉันคือผู้เขียนบทความดังกล่าวมักจะมีอคติต่อการเขียนโปรแกรมสไตล์ C ++ หากโปรแกรมนักเขียนใน C ++ เฉพาะเมื่อเขาต้องแล้วกลับไปที่ Java หรือทันทีที่เขาสามารถแล้วเขาไม่ได้แบ่งปันความคิด C ++

หนึ่งสงสัยว่านักเขียนเดียวกันหรือบางคนส่วนใหญ่ชอบผู้จัดการหน่วยความจำเก็บขยะ ฉันทำไม่ได้ แต่ฉันคิดว่าแตกต่างจากที่ทำ

พอยน์เตอร์อัจฉริยะนั้นยอดเยี่ยม แต่พวกเขาต้องรักษาจำนวนการอ้างอิงไว้ การเก็บการนับการอ้างอิงมีค่าใช้จ่ายซึ่งมักจะมีค่าใช้จ่ายพอสมควร ไม่มีอะไรผิดปกติกับการประหยัดต้นทุนเหล่านี้โดยใช้พอยน์เตอร์พอยต์โดยเฉพาะอย่างยิ่งหากพอยน์เตอร์ได้รับการจัดการโดย destructors

หนึ่งในสิ่งที่ยอดเยี่ยมเกี่ยวกับ C ++ คือการรองรับการเขียนโปรแกรมระบบฝังตัว การใช้ตัวชี้เปล่าเป็นส่วนหนึ่งของสิ่งนั้น

อัปเดต: ผู้แสดงความคิดเห็นได้สังเกตอย่างถูกต้องว่าใหม่ของ C ++unique_ptr (มีให้ตั้งแต่ TR1) จะไม่นับการอ้างอิง ผู้แสดงความคิดเห็นยังมีคำจำกัดความของ "ตัวชี้สมาร์ท" ที่แตกต่างจากที่ฉันนึกไว้ เขาอาจพูดถูกเกี่ยวกับคำจำกัดความ

การปรับปรุงเพิ่มเติม: กระทู้ความคิดเห็นด้านล่างส่องแสง ทั้งหมดแนะนำให้อ่าน


2
สำหรับการเริ่มต้นการเขียนโปรแกรมระบบฝังตัวเป็นส่วนน้อยของการเขียนโปรแกรมทั้งหมดและค่อนข้างไม่เกี่ยวข้อง C ++ เป็นภาษาที่ใช้งานทั่วไป ประการที่สองshared_ptrให้นับการอ้างอิง มีตัวชี้สมาร์ทอื่น ๆ อีกมากมายที่ไม่นับการอ้างอิงเลย ในที่สุดห้องสมุดที่กล่าวถึงจะถูกกำหนดเป้าหมายที่แพลตฟอร์มที่มีทรัพยากรเหลือเฟือ ไม่ใช่ว่าฉันเป็น downvoter แต่ทั้งหมดที่ฉันพูดคือโพสต์ของคุณเต็มไปด้วยความผิด
ลูกสุนัข

2
@thb - ฉันเห็นด้วยกับความเชื่อมั่นของคุณ DeadMG - โปรดลองใช้ชีวิตโดยไม่มีระบบฝังตัว ใช่ - ตัวชี้สมาร์ทบางตัวไม่มีค่าใช้จ่าย OP กล่าวถึงไลบรารี ตัวอย่างเช่น Boost มีชิ้นส่วนที่ใช้โดยระบบฝังตัว - แต่ตัวชี้อัจฉริยะอาจไม่เหมาะสมสำหรับบางแอปพลิเคชัน
Ed Heal

2
@EdHeal: ไม่ได้อยู่โดยไม่มีระบบฝังตัว! = การเขียนโปรแกรมสำหรับพวกเขาไม่ได้เล็ก ๆ น้อย ๆ ที่ไม่เกี่ยวข้องกับชนกลุ่มน้อย ตัวชี้สมาร์ทเหมาะสำหรับทุกสถานการณ์ที่คุณต้องการจัดการอายุการใช้งานของทรัพยากร
ลูกสุนัข

4
shared_ptrไม่มีค่าใช้จ่าย มันมีค่าใช้จ่ายหากคุณไม่ต้องการซีแมนทิกส์ความเป็นเจ้าของร่วมที่ปลอดภัยสำหรับเธรด
R. Martinho Fernandes

1
ไม่ shared_ptr มีค่าใช้จ่ายที่สำคัญเกินกว่าจำนวนขั้นต่ำที่จำเป็นสำหรับซีแมนทิกส์การเป็นเจ้าของที่ปลอดภัยต่อเธรด โดยเฉพาะมันจะจัดสรรบล็อกฮีปแยกจากวัตถุจริงที่คุณกำลังแบ่งปันเพื่อจุดประสงค์เดียวในการจัดเก็บ refcount intrusive_ptr นั้นมีประสิทธิภาพมากกว่า แต่ (เช่น shared_ptr) มันก็ถือว่าทุกตัวชี้ไปยังวัตถุนั้นจะเป็น intrusive_ptr คุณสามารถได้รับค่าใช้จ่ายที่ต่ำกว่า intrusive_ptr ด้วยตัวชี้การแชร์ที่กำหนดเองแบบที่ฉันทำในแอพของฉันแล้วใช้ T * ทุกครั้งที่คุณสามารถรับประกันได้ว่าอย่างน้อยหนึ่งตัวชี้สมาร์ทจะมีค่ามากกว่า T *
Qwertie

2

นอกจากนี้ยังมีตัวชี้สมาร์ทประเภทอื่น ๆ คุณอาจต้องการตัวชี้สมาร์ทพิเศษสำหรับบางอย่างเช่นการจำลองแบบเครือข่าย (หนึ่งที่ตรวจพบว่ามีการเข้าถึงและส่งการแก้ไขใด ๆ ไปยังเซิร์ฟเวอร์หรือบางส่วน), เก็บประวัติของการเปลี่ยนแปลงทำเครื่องหมายข้อเท็จจริงว่ามันถูกเข้าถึงเพื่อตรวจสอบเมื่อ คุณบันทึกข้อมูลลงดิสก์และอื่น ๆ ไม่แน่ใจว่าการทำเช่นนั้นในตัวชี้เป็นทางออกที่ดีที่สุด แต่การใช้ชนิดตัวชี้สมาร์ทในตัวในห้องสมุดอาจส่งผลให้ผู้คนถูกล็อคไว้และทำให้ความยืดหยุ่นลดลง

ผู้คนสามารถมีข้อกำหนดและโซลูชั่นการจัดการหน่วยความจำที่แตกต่างกันได้ทุกประเภทนอกเหนือจากตัวชี้อัจฉริยะ ฉันอาจต้องการจัดการหน่วยความจำด้วยตัวเองฉันสามารถจัดสรรพื้นที่สำหรับสิ่งต่าง ๆ ในพูลหน่วยความจำได้ดังนั้นจึงมีการจัดสรรล่วงหน้าและไม่ใช้งานจริง (มีประโยชน์สำหรับเกม) ฉันอาจใช้การรวบรวมขยะของ C ++ (C ++ 11 ทำให้สิ่งนี้เป็นไปได้แม้ว่าจะยังไม่มีอยู่) หรือบางทีฉันแค่ไม่ได้ทำอะไรขั้นสูงพอที่จะกังวลเกี่ยวกับการรบกวนพวกเขาฉันสามารถรู้ได้ว่าฉันจะไม่ลืมที่จะไม่เตรียมวัตถุอื่น ๆ บางทีฉันแค่มั่นใจในความสามารถของฉันในการจัดการหน่วยความจำโดยไม่ต้อง crutch ตัวชี้

การรวมเข้ากับ C ก็เป็นอีกปัญหาหนึ่งเช่นกัน

ปัญหาอีกประการหนึ่งคือพอยน์เตอร์อัจฉริยะเป็นส่วนหนึ่งของ STL C ++ ถูกออกแบบมาให้ใช้งานได้โดยไม่ต้องใช้ STL


" ปัญหาอื่นคือตัวชี้สมาร์ทเป็นส่วนหนึ่งของ STL " ไม่ใช่
curiousguy

0

นอกจากนี้ยังขึ้นอยู่กับว่าคุณทำงานกับโดเมนใดฉันเขียนเอ็นจิ้นเกมเพื่อหาเลี้ยงชีพเราหลีกเลี่ยงการเพิ่มพลังเช่นโรคระบาด ในเอนจิ้นหลักของเราเราได้เขียน stl ของเราเอง (เหมือนกับ ea stl)

ถ้าฉันจะเขียนแอปพลิเคชันแบบฟอร์มฉันอาจลองใช้พอยน์เตอร์พอยน์เตอร์ แต่เมื่อการจัดการหน่วยความจำเป็นลักษณะที่สองที่ไม่มีการควบคุมอย่างละเอียดในหน่วยความจำจะกลายเป็นที่น่ารำคาญที่เงียบสงบ


3
ไม่มีสิ่งเช่น "ค่าใช้จ่ายเพิ่ม"
curiousguy

4
ฉันไม่เคยมี shared_ptr ที่จะทำให้เอนจิ้นเกมของฉันช้าลงเท่าที่ควร พวกเขาเร่งกระบวนการผลิตและแก้ไขจุดบกพร่อง นอกจากนี้คุณหมายถึงอะไรโดย "ค่าใช้จ่ายเพิ่ม" นั่นเป็นผ้าห่มขนาดใหญ่ที่น่ารัก
Derpface

@currguy: มันเป็นค่าใช้จ่ายในการรวบรวมของทุกส่วนหัวและมาโคร + แม่แบบวูดู ...
einpoklum
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.