Nạp chồng hàm (Function Overloading)
Nạp chồng hàm (function overloading) cho phép định nghĩa nhiều hàm cùng tên trong C++, miễn là chúng khác nhau về số lượng hoặc kiểu dữ liệu của tham số. Trình biên dịch tự động chọn đúng phiên bản hàm dựa vào đối số được truyền vào lúc gọi.
Ví dụ cơ bản
Phần tiêu đề “Ví dụ cơ bản”#include <iostream>
int add(int a, int b) { return a + b;}
double add(double a, double b) { return a + b;}
std::string add(std::string a, std::string b) { return a + b;}
int main() { std::cout << add(2, 3) << std::endl; // 5 (gọi phiên bản int) std::cout << add(2.5, 3.5) << std::endl; // 6 (gọi phiên bản double) std::cout << add(std::string("Hello, "), std::string("World!")) << std::endl; // Hello, World! (gọi phiên bản string)
return 0;}Trình biên dịch quyết định gọi hàm nào dựa vào kiểu và số lượng đối số tại từng lời gọi cụ thể - quá trình này xảy ra tại thời điểm biên dịch, gọi là overload resolution.
Nạp chồng theo số lượng tham số
Phần tiêu đề “Nạp chồng theo số lượng tham số”int add(int a, int b) { return a + b;}
int add(int a, int b, int c) { return a + b + c;}
int main() { std::cout << add(1, 2) << std::endl; // 3 std::cout << add(1, 2, 3) << std::endl; // 6 return 0;}Quy tắc quan trọng: không thể overload chỉ khác kiểu trả về
Phần tiêu đề “Quy tắc quan trọng: không thể overload chỉ khác kiểu trả về”Hai hàm chỉ khác nhau về kiểu trả về (giữ nguyên tham số) sẽ gây lỗi biên dịch, vì trình biên dịch không thể phân biệt được lời gọi nào muốn dùng hàm nào:
int get_value(int x) { return x; }// double get_value(int x) { return x; } // LỖI! Không thể overload chỉ khác kiểu trả vềNạp chồng và tham số mặc định: cẩn thận gây mơ hồ (ambiguous)
Phần tiêu đề “Nạp chồng và tham số mặc định: cẩn thận gây mơ hồ (ambiguous)”void print(int x) { std::cout << "int: " << x << std::endl;}
void print(int x, int y = 10) { std::cout << "int, int: " << x << ", " << y << std::endl;}
int main() { // print(5); // LỖI! Mơ hồ - trình biên dịch không biết gọi hàm nào print(5, 20); // OK - chỉ khớp với hàm thứ hai return 0;}Ứng dụng thực tế
Phần tiêu đề “Ứng dụng thực tế”Overloading thường dùng để cung cấp nhiều cách gọi cùng một chức năng, giúp code ở nơi gọi trông tự nhiên hơn:
#include <iostream>#include <string>
void display(int value) { std::cout << "So nguyen: " << value << std::endl;}
void display(double value) { std::cout << "So thuc: " << value << std::endl;}
void display(const std::string& value) { std::cout << "Chuoi: " << value << std::endl;}
int main() { display(42); display(3.14); display(std::string("Hello")); return 0;}Tổng kết
Phần tiêu đề “Tổng kết”- Function overloading cho phép nhiều hàm cùng tên, khác nhau về số lượng hoặc kiểu tham số
- Trình biên dịch chọn đúng phiên bản hàm dựa vào đối số tại lời gọi cụ thể
- Không thể overload hai hàm chỉ khác nhau ở kiểu trả về
- Cẩn thận khi kết hợp overloading với tham số mặc định - có thể gây ra lời gọi mơ hồ (ambiguous call)