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

ฟังก์ชันที่ไม่สามารถ Overload ได้ใน C++

ภาพรวม Function Overloading

Function Overloading (การโอเวอร์โหลดฟังก์ชัน) คือคุณสมบัติของ C++ ที่อนุญาตให้ประกาศฟังก์ชันหลายฟังก์ชันที่มี ชื่อเดียวกัน แต่มี Parameter List (ลายเซ็น) ต่างกัน

กติกาที่ทำให้ Overload ได้

  • ชื่อฟังก์ชันเหมือนกัน
  • Parameter List ต่างกัน (จำนวน ตัวหรือ ชนิดข้อมูล)
  • Return type ไม่ถูกนับเป็นส่วนหนึ่งของ Signature

ฟังก์ชันที่ ไม่สามารถ Overload ได้

1. ฟังก์ชันที่ต่างกันเฉพาะ Return Type

// ❌ ผิด - คอมไพเลอร์ Error: redefinition
int func(int a);
float func(int a);  // เหมือนกัน parameter แตกต่าง return type เท่านั้น

2. ฟังก์ชันที่มี Default Arguments ทำให้ Signature ชนกัน

// ❌ ผิด - เรียก func(10) คอมไพเลอร์ไม่รู้เรียกตัวไหน
void func(int a, int b);
void func(int a, int b = 10);  // เรียก func(10) ได้ทั้งคู่

3. Static Member Function กับ Non-Static Member Function ที่เหมือนกัน

class MyClass {
    static void func(int x);   // ❌ ไม่สามารถ overload กับ
    void func(int x);          //    non-static version ได้
};

4. ฟังก์ชันที่ต่างกันแค่ cv-qualifiers (const/volatile) ของพารามิเตอร์ที่เป็น reference/pointer ระดับบนสุด

// ❌ ผิด - ถือว่า signature เหมือนกัน
void func(int* p);
void func(const int* p);  // top-level const ถูกละเว้น

แต่ สำหรับ reference/pointer ระดับใน (non-top-level) overload ได้:

// ✓ ถูกต้อง - overload ได้
void func(int* p);
void func(const int* p);  // wait, this is top-level...

// ✓ ถูกต้องจริง:
void func(int& r);
void func(const int& r);  // reference to const - overload ได้

5. ฟังก์ชันที่ต่างกันแค่ typedef / using alias

typedef int MyInt;
void func(int a);
void func(MyInt a);  // ❌ ผิด - MyInt คือ int เหมือนกัน

ฟังก์ชันที่ Overload ได้ (สรุป)

กรณีตัวอย่างผลลัพธ์
จำนวนพารามิเตอร์ต่างกันfunc(int), func(int, int)✓ OK
ชนิดพารามิเตอร์ต่างกันfunc(int), func(float)✓ OK
ลำดับพารามิเตอร์ต่างกันfunc(int, float), func(float, int)✓ OK
cv-qualifiers บน reference/pointer ระดับในfunc(int&), func(const int&)✓ OK
Ref vs Valuefunc(int), func(int&)✓ OK
R-value referencefunc(int&), func(int&&)✓ OK (C++11)

ตัวอย่างโค้ดสาธิต

#include <iostream>
using namespace std;

// ✓ Overload ได้: จำนวน parameter ต่างกัน
void print(int a) { cout << "One int: " << a << endl; }
void print(int a, int b) { cout << "Two ints: " << a << ", " << b << endl; }

// ✓ Overload ได้: ชนิด parameter ต่างกัน
void print(double a) { cout << "One double: " << a << endl; }
void print(const string& s) { cout << "String: " << s << endl; }

// ✓ Overload ได้: ลำดับ parameter ต่างกัน
void print(int a, double b) { cout << "int, double: " << a << ", " << b << endl; }
void print(double a, int b) { cout << "double, int: " << a << ", " << b << endl; }

// ✓ Overload ได้: const reference
void modify(int& x) { cout << "Non-const ref: " << x << endl; }
void modify(const int& x) { cout << "Const ref: " << x << endl; }

// ❌ ไม่ได้: เฉพาะ return type ต่างกัน
// int getValue(); 
// double getValue(); // Error!

// ❌ ไม่ได้: default argument ทำให้ ambiguous
// void func(int a, int b);
// void func(int a, int b = 10);

int main() {
    print(10);
    print(10, 20);
    print(3.14);
    print("Hello");
    print(1, 2.5);
    print(2.5, 1);
    
    int x = 5;
    modify(x);       // เรียก non-const version
    modify(10);      // เรียก const version (rvalue bind to const ref)
    
    return 0;
}

ผลลัพธ์ตัวอย่าง

One int: 10
Two ints: 10, 20
One double: 3.14
String: Hello
int, double: 1, 2.5
double, int: 2.5, 1
Non-const ref: 5
Const ref: 10

Best Practices

  • Overload เฉพาะเมื่อทำหน้าที่ "เหมือนกัน" แต่รับข้อมูลต่างชนิดกัน
  • หลีกเลี่ยง Default Arguments ที่ทำให้เกิด Ambiguity
  • ใช้ explicit สำหรับ Constructor เพื่อป้องกัน Implicit Conversion ที่ทำให้ Overload Resolution ยาก
  • Document ชัดเจนว่าแต่ละ overload ทำอะไรต่างกันอย่างไร

Overload Resolution (การคัดเลือก Overload)

C++ ใช้กติกา Best Match:

  1. Exact Match (ไม่ต้อง conversion)
  2. Promotion (int → double, float → double)
  3. Conversion (int → float, double → int)
  4. User-defined Conversion
  5. Ellipsis (...) - ตัวเลือกสุดท้าย

ถ้ามีหลายฟังก์ชันเท่าเทียมกัน → Ambiguity Error