ข้ามไปที่เนื้อหา

Ch13: Function Overloading

TL;DR: Function Overloading: C++ อนุญาตให้ประกาศฟังก์ชันหลายตัวโดยใช้ชื่อเดียวกันได้ ตราบใดที่รายการพารามิเตอร์ต่างกัน (ชนิดข้อมูล, ลำดับ หรือจำนวน) โดย Compiler จะเลือกฟังก์ชันที่เหมาะสมที่สุดตามอาร์กิวเมนต์ที่ส่งเข้ามา

⚡ Quick Reference

#include <iostream>
#include <string_view>
#include <iterator>

// Overloads ที่จำแนกตามประเภทของพารามิเตอร์
int max(int a, int b) { return (a > b) ? a : b; }
double max(double a, double b) { return (a > b) ? a : b; }

// Overloads ที่จำแนกตามลำดับของพารามิเตอร์
double max(int a, double b) { return (a > b) ? a : b; }
double max(double a, int b) { return (a > b) ? a : b; }

// Overloads ที่จำแนกตามจำนวนของพารามิเตอร์
double max(double a, int b, int c) { return a + b + c; }

// Overload สำหรับรับข้อมูลแบบ string view
std::string_view max(std::string_view a, std::string_view b) { return (a > b) ? a : b; }

// Overloads สำหรับจำแนกระหว่าง pointer-to-const กับ mutable pointer
int max(int* a, int* b) { return (*a > *b) ? *a : *b; }
int max(const int* a, const int* b) { return (*a > *b) ? *a : *b; }

// Overloads สำหรับจำแนกระหว่าง const reference กับ mutable reference
int max(int& a, int& b) { return (a > b) ? a : b; }
int max(const int& a, const int& b) { return (a > b) ? a : b; }

int main() {
    int arr[] = {1, 2, 3};
    size_t size = std::size(arr); // std::size(array) - คำนวณจำนวนสมาชิกในอาเรย์

    auto result = max(10, 20); // คาดเดาชนิดข้อมูลขาส่งกลับของโอเวอร์โหลดที่ถูกเลือก
    return 0;
}

🧠 Core Concepts

  • Function Overloading: C++ อนุญาตให้ประกาศฟังก์ชันหลายตัวโดยใช้ชื่อเดียวกันได้ ตราบใดที่รายการพารามิเตอร์ต่างกัน (ชนิดข้อมูล, ลำดับ หรือจำนวน) โดย Compiler จะเลือกฟังก์ชันที่เหมาะสมที่สุดตามอาร์กิวเมนต์ที่ส่งเข้ามา
  • Signature Constraints: ลายเซ็นของฟังก์ชัน (Function Signature) จะประกอบด้วยชื่อและรายการพารามิเตอร์เท่านั้น โดยประเภทการส่งคืน (Return type) ไม่ได้เป็นส่วนหนึ่งของลายเซ็น ทำให้ไม่สามารถประกาศฟังก์ชันที่ต่างกันเพียงแค่ Return type ได้
  • Overload Resolution & Ambiguity: Compiler จะเลือกฟังก์ชันเป้าหมายที่ดีที่สุดโดยใช้ชนิดข้อมูลของอาร์กิวเมนต์ หากเกิดกรณีที่การแปลงชนิดข้อมูลโดยนัย (Implicit Conversion) ทำให้เข้าคู่กับฟังก์ชันได้ดีเท่าๆ กันหลายตัว Compiler จะแจ้งแครชเป็นข้อผิดพลาดแบบกำกวม

⚠️ Pitfalls (Quick Scan)

ข้อผิดพลาด วิธีแก้
สร้างฟังก์ชัน Overload ที่ต่างกันเฉพาะประเภทการส่งคืน (Return type) เปลี่ยนชนิดข้อมูล จำนวน หรือลำดับของพารามิเตอร์แทน
สร้างฟังก์ชัน Overload ที่ทำให้เกิดผลการแปลงชนิดข้อมูลโดยนัยในระดับเท่ากัน หลีกเลี่ยงการสร้าง Overload ที่เปิดช่องให้แปลงประเภทข้อมูลแบบซ้ำซ้อนกันได้ (20.4)
ใช้ Const บนตัวแปร Pointer (Top-level const) เพื่อพยายามสร้างฟังก์ชัน Overload ใหม่ ใช้ Const บนเป้าหมายที่ชี้ (Pointer-to-const) ในการทำ Overload แทน (20.6)
สร้างฟังก์ชัน Overload ร่วมกับฟังก์ชันที่มีพารามิเตอร์แบบ Default เลี่ยงการใส่ค่า Default ในพารามิเตอร์ให้กับฟังก์ชันที่มีการทำ Overload (20.8)

📖 Full Details

Cause → Effect → Fix พร้อม timestamp (คลิกเพื่อดู) * **สร้างฟังก์ชัน Overload ที่ต่างกันเฉพาะประเภทการส่งคืน (Return type)** -> **เกิด Compile-time error เนื่องจาก Return type ไม่รวมอยู่ในลายเซ็นฟังก์ชัน** -> **เปลี่ยนชนิดข้อมูล จำนวน หรือลำดับของพารามิเตอร์แทน (01:05)** * **สร้างฟังก์ชัน Overload ที่ทำให้เกิดผลการแปลงชนิดข้อมูลโดยนัยในระดับเท่ากัน** -> **เกิด Compile-time error ตอนเรียกใช้งาน เนื่องจาก Compiler ไม่รู้ว่าต้องเลือกฟังก์ชันตัวใด** -> **หลีกเลี่ยงการสร้าง Overload ที่เปิดช่องให้แปลงประเภทข้อมูลแบบซ้ำซ้อนกันได้ (20.4)** * **ใช้ Const บนตัวแปร Pointer (Top-level const) เพื่อพยายามสร้างฟังก์ชัน Overload ใหม่** -> **เกิด Compile-time error เนื่องจาก compiler มองว่ามีลายเซ็นทับซ้อนกับพอยน์เตอร์ธรรมดา** -> **ใช้ Const บนเป้าหมายที่ชี้ (Pointer-to-const) ในการทำ Overload แทน (20.6)** * **สร้างฟังก์ชัน Overload ร่วมกับฟังก์ชันที่มีพารามิเตอร์แบบ Default** -> **เกิด Compile-time error เมื่อเรียกใช้ฟังก์ชันโดยละเว้นการป้อนอาร์กิวเมนต์** -> **เลี่ยงการใส่ค่า Default ในพารามิเตอร์ให้กับฟังก์ชันที่มีการทำ Overload (20.8)**

📎 Repo Files

  • 20.FunctionOverloading/20.2OverloadingWithDifferentParameters/main.cpp
  • 20.FunctionOverloading/20.3OverloadingWithPointerParameters/main.cpp
  • 20.FunctionOverloading/20.4OverloadingWithReferenceParameters/main.cpp
  • 20.FunctionOverloading/20.5OverloadingWithConstParametersByValue/main.cpp
  • 20.FunctionOverloading/20.6OverloadingWithConstPointerAndPointerToConstParameters/main.cpp
  • 20.FunctionOverloading/20.7OverloadingWithConstReferences/main.cpp
  • 20.FunctionOverloading/20.8OverloadsWithDefaultParameters/main.cpp