บอกว่าผมได้เรียนFoobar
ที่ใช้ (ขึ้นอยู่กับ) Widget
ระดับ ในวันเฒ่าที่ดีWidget
wolud จะถูกประกาศให้เป็นสนามในFoobar
หรืออาจจะเป็นตัวชี้ที่ฉลาดถ้าต้องการพฤติกรรม polymorphic และมันจะเริ่มต้นได้ใน constructor:
class Foobar {
Widget widget;
public:
Foobar() : widget(blah blah blah) {}
// or
std::unique_ptr<Widget> widget;
public:
Foobar() : widget(std::make_unique<Widget>(blah blah blah)) {}
(…)
};
และเราจะพร้อมทุกอย่างให้เรียบร้อย น่าเสียดายที่วันนี้เด็ก ๆ จาวาจะหัวเราะเยาะเราเมื่อพวกเขาเห็นมันและอย่างถูกต้องตามที่คู่รักFoobar
และWidget
ร่วมกัน วิธีแก้ปัญหานั้นง่ายมาก: ใช้การฉีดพึ่งพาเพื่อสร้างการพึ่งพาจากFoobar
ชั้นเรียน แต่แล้ว C ++ ก็บังคับให้เราคิดถึงการเป็นเจ้าของการพึ่งพา การแก้ปัญหาทั้งสามอยู่ในใจ:
ตัวชี้ที่ไม่ซ้ำ
class Foobar {
std::unique_ptr<Widget> widget;
public:
Foobar(std::unique_ptr<Widget> &&w) : widget(w) {}
(…)
}
Foobar
อ้างสิทธิ์ความเป็นเจ้าของ แต่เพียงผู้เดียวของWidget
ที่ถูกส่งผ่านไป นี่มีข้อดีดังต่อไปนี้:
- ผลกระทบต่อประสิทธิภาพมีน้อยมาก
- มันปลอดภัยเนื่องจาก
Foobar
สามารถควบคุมอายุการใช้งานWidget
ได้ดังนั้นจึงมั่นใจได้ว่าWidget
จะไม่หายไปทันที - ปลอดภัยที่
Widget
จะไม่รั่วไหลและจะถูกทำลายอย่างเหมาะสมเมื่อไม่ต้องการใช้อีกต่อไป
อย่างไรก็ตามสิ่งนี้มีค่าใช้จ่าย:
- มันวางข้อ จำกัด เกี่ยวกับวิธีการใช้งาน
Widget
อินสแตนซ์เช่นไม่มีการจัดสรรสแต็กWidgets
สามารถใช้ไม่Widget
สามารถใช้ร่วมกัน
ตัวชี้ที่ใช้ร่วมกัน
class Foobar {
std::shared_ptr<Widget> widget;
public:
Foobar(const std::shared_ptr<Widget> &w) : widget(w) {}
(…)
}
นี่อาจใกล้เคียงที่สุดกับ Java และภาษาที่รวบรวมขยะอื่น ๆ ข้อดี:
- เป็นสากลมากขึ้นเพราะจะช่วยให้การแบ่งปันการพึ่งพา
- รักษาความปลอดภัย (จุด 2 และ 3) ของ
unique_ptr
การแก้ปัญหา
ข้อเสีย:
- สิ้นเปลืองทรัพยากรเมื่อไม่มีการแบ่งปัน
- ยังคงต้องการการจัดสรรฮีปและไม่อนุญาตวัตถุที่จัดสรรสแต็ก
ตัวชี้การสังเกตเฒ่าล้วน
class Foobar {
Widget *widget;
public:
Foobar(Widget *w) : widget(w) {}
(…)
}
วางตัวชี้ดิบไว้ในชั้นเรียนและเปลี่ยนภาระการเป็นเจ้าของให้คนอื่น ข้อดี:
- ง่ายๆเท่าที่จะทำได้
Widget
ยูนิเวอร์แซยอมรับเพียงใด
จุดด้อย:
- ไม่ปลอดภัยอีกต่อไป
- เปิดตัวอีกกิจการหนึ่งที่รับผิดชอบในการเป็นเจ้าของของทั้งสองและ
Foobar
Widget
แม่แบบการเขียนโปรแกรมบ้า ๆ บอ ๆ
ข้อดีอย่างเดียวที่ฉันคิดได้ก็คือฉันสามารถอ่านหนังสือทั้งหมดที่ฉันไม่ได้หาเวลาขณะที่ซอฟต์แวร์กำลังสร้าง;)
ฉันเอนสู่โซลูชันที่สามเนื่องจากเป็นสากลมากที่สุดมีบางสิ่งที่ต้องจัดการFoobars
ต่อไปดังนั้นการจัดการจึงWidgets
เป็นการเปลี่ยนแปลงที่ง่าย อย่างไรก็ตามการใช้ตัวชี้แบบดิบทำให้ฉันรำคาญใจในทางกลับกันตัวเลือกสมาร์ทพอยต์รู้สึกผิดกับฉันเพราะพวกเขาทำให้ผู้บริโภคที่พึ่งพิง จำกัด การสร้างการพึ่งพานั้น
ฉันพลาดอะไรไปรึเปล่า? หรือเพียงแค่การพึ่งพาการฉีดใน C ++ ไม่ใช่เรื่องไม่สำคัญ? ชั้นควรเป็นเจ้าของการพึ่งพาหรือเพียงแค่สังเกตพวกเขา?
Foobar
เป็นเจ้าของคนเดียว? ในกรณีเก่ามันง่าย แต่ปัญหากับ DI อย่างที่ฉันเห็นก็คือมันแยกชั้นจากการสร้างการพึ่งพามันก็แยกตัวมันออกจากการเป็นเจ้าของการพึ่งพาเหล่านั้นด้วย ในสภาพแวดล้อมที่เก็บขยะเช่น Java นั่นไม่ใช่ปัญหา ใน C ++ นี่คือ
std::unique_ptr
เป็นหนทางที่จะไป คุณสามารถใช้std::move()
เพื่อโอนการเป็นเจ้าของทรัพยากรจากขอบเขตบนไปยังคลาส