คำตอบส่วนใหญ่ที่นี่ไม่สามารถแก้ปัญหาความกำกวมโดยธรรมชาติในการมีตัวชี้แบบดิบในลายเซ็นฟังก์ชันในแง่ของการแสดงเจตนา ปัญหาดังต่อไปนี้:
- ผู้เรียกไม่ทราบว่าตัวชี้ชี้ไปที่วัตถุเดียวหรือไปยังจุดเริ่มต้นของ "อาร์เรย์" ของวัตถุ 
- ผู้เรียกไม่ทราบว่าตัวชี้ "เป็นเจ้าของ" หน่วยความจำที่ชี้ไป IE ไม่ว่าจะเป็นฟังก์ชั่นควรเพิ่มหน่วยความจำหรือไม่ ( - foo(new int)- นี่เป็นหน่วยความจำรั่วหรือไม่)
 
- ผู้เรียกไม่ทราบว่า- nullptrสามารถส่งผ่านไปยังฟังก์ชันได้อย่างปลอดภัยหรือไม่
 
ปัญหาทั้งหมดเหล่านี้ได้รับการแก้ไขโดยการอ้างอิง:
- การอ้างอิงอ้างถึงวัตถุเดียวเสมอ 
- การอ้างอิงไม่เคยเป็นเจ้าของหน่วยความจำที่อ้างถึง แต่เป็นเพียงมุมมองในหน่วยความจำ 
- ข้อมูลอ้างอิงต้องไม่เป็นค่าว่าง 
สิ่งนี้ทำให้การอ้างอิงเป็นตัวเลือกที่ดีกว่าสำหรับการใช้งานทั่วไป อย่างไรก็ตามการอ้างอิงไม่สมบูรณ์ - มีปัญหาใหญ่สองสามข้อที่ต้องพิจารณา
- ไม่มีทางอ้อมอย่างชัดเจน นี่ไม่ใช่ปัญหากับตัวชี้แบบดิบเนื่องจากเราต้องใช้ตัว&ดำเนินการเพื่อแสดงว่าเรากำลังผ่านตัวชี้ ตัวอย่างเช่น,int a = 5; foo(a);มันไม่ชัดเจนเลยที่นี่ว่า a กำลังถูกส่งผ่านโดยการอ้างอิงและสามารถแก้ไขได้
- Nullability จุดอ่อนของพอยน์เตอร์นี้สามารถเป็นจุดแข็งได้เมื่อเราต้องการให้การอ้างอิงของเราเป็นโมฆะ เมื่อเห็นว่าstd::optional<T&>ไม่ถูกต้อง (สำหรับเหตุผลที่ดี) พอยน์เตอร์จะบอกเราว่าคุณต้องการความถูกต้อง
ดังนั้นดูเหมือนว่าเมื่อเราต้องการการอ้างอิงที่เป็นโมฆะพร้อมกับการบอกทางอย่างชัดแจ้งเราควรไปถึง T*ใช่ไหม? ไม่ถูกต้อง!
นามธรรม
ในความสิ้นหวังของเราสำหรับความไร้ผลเราอาจถึงT*และเพียงเพิกเฉยต่อข้อบกพร่องและความกำกวมเชิงความหมายที่ระบุไว้ก่อนหน้า แต่เราควรไปถึงสิ่งที่ C ++ ทำได้ดีที่สุด: สิ่งที่เป็นนามธรรม ถ้าเราเพียงแค่เขียนคลาสที่ล้อมรอบพอยน์เตอร์เราจะได้รับการแสดงออกเช่นเดียวกับความไร้ประสิทธิภาพและความไม่แน่นอนทางอ้อม
template <typename T>
struct optional_ref {
  optional_ref() : ptr(nullptr) {}
  optional_ref(T* t) : ptr(t) {}
  optional_ref(std::nullptr_t) : ptr(nullptr) {}
  T& get() const {
    return *ptr;
  }
  explicit operator bool() const {
    return bool(ptr);
  }
private:
  T* ptr;
};
นี่เป็นอินเทอร์เฟซที่ง่ายที่สุดที่ฉันสามารถทำได้ แต่ทำงานได้อย่างมีประสิทธิภาพ จะช่วยให้การเริ่มต้นการอ้างอิงตรวจสอบว่ามีค่าอยู่และเข้าถึงค่า เราสามารถใช้มันได้เช่น:
void foo(optional_ref<int> x) {
  if (x) {
    auto y = x.get();
    // use y here
  }
}
int x = 5;
foo(&x); // explicit indirection here
foo(nullptr); // nullability
เราบรรลุเป้าหมายของเราแล้ว! ตอนนี้ให้เราเห็นประโยชน์เมื่อเทียบกับตัวชี้ดิบ
- อินเทอร์เฟซแสดงอย่างชัดเจนว่าการอ้างอิงควรอ้างถึงวัตถุเดียวเท่านั้น
- เห็นได้ชัดว่ามันไม่ได้เป็นเจ้าของหน่วยความจำมันหมายถึงเนื่องจากมันไม่มี destructor ที่ผู้ใช้กำหนดและไม่มีวิธีการลบหน่วยความจำ
- ผู้โทรรู้nullptrสามารถส่งต่อได้เนื่องจากผู้เขียนฟังก์ชั่นร้องขออย่างชัดเจนoptional_ref
เราสามารถทำให้ส่วนต่อประสานที่ซับซ้อนมากขึ้นจากที่นี่เช่นการเพิ่มตัวดำเนินการความเท่าเทียมกัน monadic get_orและmapส่วนต่อประสานซึ่งเป็นวิธีการที่ได้รับคุณค่าหรือส่งข้อยกเว้นconstexprสนับสนุน ที่สามารถทำได้โดยคุณ
โดยสรุปแทนที่จะใช้พอยน์เตอร์แบบดิบให้เหตุผลเกี่ยวกับความหมายของพอยน์เตอร์ในรหัสของคุณและใช้ประโยชน์จากไลบรารี่มาตรฐานที่เป็นนามธรรมหรือเขียนของคุณเอง สิ่งนี้จะปรับปรุงรหัสของคุณอย่างมีนัยสำคัญ
               
              
newการสร้างตัวชี้และปัญหาที่เกิดจากการเป็นเจ้าของ