บอกว่าผมได้เรียนFoobarที่ใช้ (ขึ้นอยู่กับ) Widgetระดับ ในวันเฒ่าที่ดีWidgetwolud จะถูกประกาศให้เป็นสนามใน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ยูนิเวอร์แซยอมรับเพียงใด
จุดด้อย:
- ไม่ปลอดภัยอีกต่อไป
- เปิดตัวอีกกิจการหนึ่งที่รับผิดชอบในการเป็นเจ้าของของทั้งสองและ
FoobarWidget
แม่แบบการเขียนโปรแกรมบ้า ๆ บอ ๆ
ข้อดีอย่างเดียวที่ฉันคิดได้ก็คือฉันสามารถอ่านหนังสือทั้งหมดที่ฉันไม่ได้หาเวลาขณะที่ซอฟต์แวร์กำลังสร้าง;)
ฉันเอนสู่โซลูชันที่สามเนื่องจากเป็นสากลมากที่สุดมีบางสิ่งที่ต้องจัดการFoobarsต่อไปดังนั้นการจัดการจึงWidgetsเป็นการเปลี่ยนแปลงที่ง่าย อย่างไรก็ตามการใช้ตัวชี้แบบดิบทำให้ฉันรำคาญใจในทางกลับกันตัวเลือกสมาร์ทพอยต์รู้สึกผิดกับฉันเพราะพวกเขาทำให้ผู้บริโภคที่พึ่งพิง จำกัด การสร้างการพึ่งพานั้น
ฉันพลาดอะไรไปรึเปล่า? หรือเพียงแค่การพึ่งพาการฉีดใน C ++ ไม่ใช่เรื่องไม่สำคัญ? ชั้นควรเป็นเจ้าของการพึ่งพาหรือเพียงแค่สังเกตพวกเขา?
Foobarเป็นเจ้าของคนเดียว? ในกรณีเก่ามันง่าย แต่ปัญหากับ DI อย่างที่ฉันเห็นก็คือมันแยกชั้นจากการสร้างการพึ่งพามันก็แยกตัวมันออกจากการเป็นเจ้าของการพึ่งพาเหล่านั้นด้วย ในสภาพแวดล้อมที่เก็บขยะเช่น Java นั่นไม่ใช่ปัญหา ใน C ++ นี่คือ
std::unique_ptrเป็นหนทางที่จะไป คุณสามารถใช้std::move()เพื่อโอนการเป็นเจ้าของทรัพยากรจากขอบเขตบนไปยังคลาส