Cập nhật lần cuối: 26 Feb, 2026

Khi viết các chương trình C++, đặc biệt là trong các dự án lớn, việc tổ chức mã nguồn thành nhiều tệp là điều cần thiết để tăng khả năng đọc và bảo trì. Thông thường, điều này liên quan đến việc sử dụng tệp header, với các phần mở rộng .h hoặc .hpp. Nhưng sự khác nhau giữa hai loại này là gì, và bạn nên dùng loại nào?
Trong bài viết này, chúng tôi sẽ phân tích sự khác nhau giữa các tệp .h và .hpp, khám phá lịch sử của chúng, và đưa ra hướng dẫn thực hành tốt nhất.
Hiểu về các tệp Header trong C++
Các tệp header chứa khai báo cho hàm, lớp, hằng số và macro mà bạn có thể đưa vào nhiều tệp nguồn. Các tệp này sau đó được đưa vào các tệp .cpp (nguồn C++) bằng chỉ thị #include.
Nội dung thường gặp trong tệp Header
- Định nghĩa lớp
- Khai báo hàm
- Định nghĩa hằng số
- Macro
- Mẫu (trong một số trường hợp)
Các tệp .h
Tệp .h là gì?
Các tệp .h là các tệp header truyền thống và lần đầu tiên được sử dụng rộng rãi trong ngôn ngữ lập trình C. Chúng vẫn được dùng trong cả dự án C và C++ để khai báo giao diện.
Ví dụ sử dụng:
// mathutils.h
#ifndef MATHUTILS_H
#define MATHUTILS_H
int add(int a, int b);
int subtract(int a, int b);
#endif
Ưu điểm:
- Được công nhận rộng rãi (được dùng trong cả C và C++).
- Thích hợp cho các dự án có cả mã C và C++.
Nhược điểm:
- Có thể gây mơ hồ trong các dự án C++ về việc tệp này là kiểu C hay kiểu C++.
Các tệp .hpp
Tệp .hpp là gì?
Các tệp .hpp là các tệp header dành riêng cho C++. Chúng hoạt động giống như các tệp .h nhưng được dùng để chỉ rõ rằng header này dành cho mã C++.
Ví dụ sử dụng:
// vectorutils.hpp
#ifndef VECTORUTILS_HPP
#define VECTORUTILS_HPP
#include <vector>
std::vector<int> filter_even(const std::vector<int>& input);
#endif
Ưu điểm:
- Rõ ràng chỉ ra rằng tệp này dành cho mã C++.
- Tránh nhầm lẫn khi kết hợp C và C++.
- Hữu ích trong các dự án đa ngôn ngữ hoặc các nhóm tuân thủ quy tắc đặt tên nghiêm ngặt.
Nhược điểm:
- Ít phổ biến hơn trong các codebase cũ.
- Một số hệ thống legacy không nhận diện được
.h.
.h vs .hpp: Những điểm khác biệt chính
| Tính năng | Tệp .h | Tệp .hpp |
|---|---|---|
| Liên kết ngôn ngữ | C và C++ | Chỉ C++ |
| Quy ước hay Quy tắc? | Quy ước | Quy ước |
| Sử dụng trong dự án C++ | Thông thường | Ưu tiên bởi một số người để rõ ràng |
| Hỗ trợ mẫu | Có | Có |
| Mơ hồ mã | Có thể xảy ra trong dự án đa ngôn ngữ | Ít khả năng xảy ra |
Thực hành tốt nhất để chọn giữa .h và .hpp
Dưới đây là một số hướng dẫn chung để giúp bạn lựa chọn:
Sử dụng .h nếu:
- Bạn đang viết mã cần tương thích cả với C và C++.
- Bạn đang bảo trì hoặc mở rộng code legacy đã sử dụng
.h.
Sử dụng .hpp nếu:
- Bạn muốn làm rõ rằng tệp này chỉ dành cho C++.
- Bạn đang làm việc trong dự án chỉ dùng C++ hoặc sử dụng các tính năng đặc thù của C++ như lớp, mẫu và namespace.
Cấu trúc dự án phổ biến
Ví dụ với .h:
project/
├── main.cpp
├── mathutils.h
└── mathutils.cpp
Ví dụ với .hpp:
project/
├── main.cpp
├── vectorutils.hpp
└── vectorutils.cpp
Cả hai cấu trúc đều hợp lệ; sự khác nhau chủ yếu nằm ở độ rõ ràng và sở thích của nhóm.
Kết luận
Việc lựa chọn giữa .h và .hpp chủ yếu là vấn đề quy ước, không phải chức năng. Cả hai đều phục vụ cùng một mục đích: khai báo giao diện và mã chia sẻ giữa nhiều tệp nguồn C++.
Tuy nhiên, đối với mã chỉ dành cho C++, việc sử dụng .hpp có thể làm cho ý định của bạn rõ ràng hơn và giúp tránh nhầm lẫn trong các codebase lớn—đặc biệt là những dự án có nhiều ngôn ngữ. Đối với các dự án đa ngôn ngữ hoặc legacy, .h vẫn có thể là lựa chọn phù hợp.
Điều quan trọng cần nhớ:
Sử dụng
.hppkhi bạn muốn chỉ ra “đây chỉ là mã C++” — dùng.hnếu bạn đang làm việc trong môi trường hỗn hợp C và C++.