Trong C++, nạp chồng hàm (function overloading) cho phép nhiều hàm cùng tên nhưng khác tham số. Tuy nhiên, có những trường hợp không được phép nạp chồng do trình biên dịch coi chúng là trùng lặp.
1. Chỉ khác kiểu trả về
// LỖI: Chỉ khác kiểu trả về
int my_func() { return 5; }
char my_func() { return 'd'; }
Trình biên dịch không biết gọi hàm nào khi viết my_func().
2. Hàm thành viên static vs non-static cùng tên và tham số
class MyClass {
static void func(int x); // LỖI
void func(int x); // Trùng với static version
};
3. Tham số con trỏ vs mảng (tương đương)
// LỖI: int* và int[] là như nhau trong tham số hàm
int my_func(int *arr);
int my_func(int arr[]);
Khi truyền mảng vào hàm, nó decay thành con trỏ.
4. Tham số có/không có const/volatile (top-level)
// LỖI: const/volatile top-level bị bỏ qua
int my_func(int x);
int my_func(const int x);
int my_func(volatile int x);
Lưu ý: const int* vs int* KHÁC nhau (const ở cấp con trỏ).
5. Chỉ khác tham số mặc định (default argument)
// LỖI: Chỉ khác default argument
int my_func(int a, int b);
int my_func(int a, int b = 50);
Gọi my_func(1, 2) gây ambiguous.
Tóm tắt quy tắc
| Khác biệt | Có nạp chồng được? |
|---|---|
| Số lượng tham số | ✅ Có |
| Kiểu tham số (khác bản chất) | ✅ Có |
| const/volatile ở cấp con trỏ/tham chiếu | ✅ Có |
| Chỉ khác kiểu trả về | ❌ Không |
| static vs non-static thành viên | ❌ Không |
| con trỏ vs mảng | ❌ Không |
| const/volatile top-level | ❌ Không |
| Chỉ khác default argument | ❌ Không |
Ví dụ hợp lệ (có thể nạp chồng)
// Khác kiểu tham số
void print(int x);
void print(double x);
void print(const char* s);
// Khác số lượng
void draw();
void draw(int x);
void draw(int x, int y);
// Khác const ở cấp con trỏ
void func(int* p);
void func(const int* p);
// Khác tham chiếu const
void func(int& r);
void func(const int& r);