Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

การเรียก Member Function ผ่าน NULL Object Pointer ใน C++

ภาพรวม

ใน C++ สามารถเรียก Member Function ผ่าน NULL Pointer ได้ แต่เป็น Undefined Behavior (UB) ผลลัพธ์ขึ้นอยู่กับ Compiler และ Optimization Level ไม่ควรทำใน Production Code

ตัวอย่างโค้ด (แสดงพฤติกรรม - ไม่แนะนำให้ทำตาม)

#include <iostream>
using namespace std;

class Demo {
public:
    void fun() {
        cout << "This member function is called through Null object pointer.";
    }
};

int main() {
    Demo* ptr = nullptr;
    ptr->fun();  // Undefined Behavior!
    return 0;
}

ผลลัพธ์ (บน Compiler บางตัว)

This member function is called through Null object pointer.

ทำไมถึง "ทำงานได้" บนบาง Compiler?

  1. Non-virtual Member Functions: ถูก Compile เป็น Regular Function ที่รับ this Pointer เป็น Parameter แรก
  2. ถ้า Function ไม่เข้าถึง Data Members (ไม่ dereference this) โค้ดอาจรันได้
  3. Compiler ไม่ตรวจสอบ Null Pointer ก่อนเรียก (Performance)

เมื่อไหร่จะ Crash/UB จริง?

  • เข้าถึง Data Member (this->member)
  • เรียก Virtual Function (ต้องอ่าน VTable ผ่าน this)
  • Dynamic Cast / typeid
  • Compiler Optimization เปิดสูง (อาจลบโค้ดที่ UB ออกไป)

ตัวอย่างที่ Crash


class CrashDemo {
    int data = 42;
public:
    void unsafe() { cout << data; }  // Crash: dereference null this
    virtual void virtualFunc() {}    // Crash: vtable access
};

Best Practices - ห้ามทำ!

❌ อย่าเรียก Member Function ผ่าน Null Pointer

  • เป็น Undefined Behavior - ไม่มีการรับประกันพฤติกรรม
  • อาจทำงานตอน Debug แต Crash ตอน Release (Optimization)
  • Static Analysis Tools (Clang-Tidy, PVS-Studio) จะเตือน

วิธีป้องกัน


// 1. ตรวจสอบ Null ก่อนเรียก
if (ptr != nullptr) {
    ptr->fun();
}

// 2. ใช้ References (ไม่สามารถเป็น Null ได้)
void safeCall(Demo& obj) {  // Reference ไม่เป็น Null
    obj.fun();
}

// 3. ใช้ Smart Pointers
unique_ptr<Demo> ptr = make_unique<Demo>();
ptr->fun();  // Safe: ptr ไม่เป็น Null (ถ้า Check ก่อน)

// 4. Contract Programming (C++20)
[[assert: ptr != nullptr]] ptr->fun();

ข้อเท็จจริงทางเทคนิค

  • C++ Standard: "If the object pointer is null, the behavior is undefined" ([expr.call])
  • Microsoft Visual Studio: มักทำงาน (Non-virtual, No Data Access)
  • GCC/Clang: อาจ Optimize ทำให้ Crash หรือทำงานผิดปกติ
  • Static Analysis: ตรวจพบได้ด้วย -Wnull-dereference