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

Default Virtual Behavior ใน C++ vs Java: ความแตกต่างพื้นฐาน

ความแตกต่างพื้นฐานระหว่าง C++ และ Java เกี่ยวกับ virtual functions ส่งผลต่อการออกแบบ class hierarchy และประสิทธิภาพ

ความแตกต่างหลัก

ด้านC++Java
DefaultNon-virtual (static binding)Virtual (dynamic binding)
Keyword เพื่อ virtualvirtualไม่ต้องใส่ (default)
Keyword เพื่อ non-virtualไม่ใส่ virtual / final (C++11)final
Performanceเร็วกว่า (ไม่มี vtable lookup)ช้ากว่า (เสมอ vtable lookup)
Design PhilosophyPay for what you useSafety by default

ตัวอย่าง C++: Non-virtual by Default

#include <iostream>

using namespace std;

class Base {
public:
    void show() {  // Non-virtual
        cout << "In Base\n";
    }
};

class Derived : public Base {
public:
    void show() {  // Hides Base::show(), ไม่ใช่ override
        cout << "In Derived\n";
    }
};

int main() {
    Derived d;
    Base& b = d;     // Reference to Base
    Base* bp = &d;   // Pointer to Base
    
    d.show();   // "In Derived" - static binding (compile-time)
    b.show();   // "In Base"    - static binding (compile-time)!
    bp->show(); // "In Base"    - static binding (compile-time)!
    
    return 0;
}

ผลลัพธ์ C++

In Derived
In Base
In Base

ตัวอย่าง C++: ทำให้ Virtual

class Base {
public:
    virtual void show() {  // เพิ่ม virtual
        cout << "In Base\n";
    }
    virtual ~Base() {}     // Virtual destructor สำคัญ!
};

class Derived : public Base {
public:
    void show() override {  // C++11: override specifier
        cout << "In Derived\n";
    }
};

int main() {
    Derived d;
    Base& b = d;
    b.show();  // "In Derived" - dynamic binding (runtime)!
}

ตัวอย่าง Java: Virtual by Default

class Base {
    public void show() {  // Virtual by default
        System.out.println("In Base");
    }
}

class Derived extends Base {
    @Override
    public void show() {
        System.out.println("In Derived");
    }
}

public class Main {
    public static void main(String[] args) {
        Base b = new Derived();
        b.show();  // "In Derived" - dynamic binding เสมอ
    }
}

ผลลัพธ์ Java

In Derived

ทำไม C++ เลือก Non-virtual by Default?

  1. Performance: Non-virtual เรียกโดย direct call (inline ได้) Virtual ใช้ vtable lookup (indirect call)
  2. Size: Class ไม่มี virtual functions ไม่มี vptr (ประหยัดหน่วยความจำ)
  3. Control: Programmer ตัดสินใจเองเมื่อไหร่ต้องการ polymorphism
  4. Backward compatibility: เข้ากันได้กับ C struct

Best Practices ใน C++

  • ใช้ virtual เมื่อต้องการ polymorphic behavior
  • ใช้ override (C++11) เพื่อป้องกัน typo ใน signature
  • ใช้ final (C++11) เพื่อห้าม override ต่อ
  • เสมอให้ Base class มี virtual destructor ถ้ามี virtual functions
  • หลีกเลี่ยงการเรียก virtual functions ใน constructor/destructor

สรุป

C++ ให้ความควบคุมและประสิทธิภาพสูงสุด (opt-in polymorphism) ส่วน Java ให้ความปลอดภัยและความง่าย (opt-out polymorphism) ทั้งสองแนวคิดมี trade-offs ที่ชัดเจน