Tôi có một mã trong đó tôi #include
.Có tổng cộng ba tệp:
Một tệp tiêu đề - bao gồm:stdint.h
Và stdlib.h
.Định nghĩa một số hàm, cấu trúc (chẳng hạn như abc) và một số macro #define. Một trong những chức năng là
int func(int, uint32_t, size_t, abc*);
Tệp cpp chứa nhiều phương thức, bao gồm cả định nghĩa hàm trong tệp .h.
Một main.cpp có các phương thức gọi hàm main() trong tệp .h (tệp đầy đủ bên dưới). Tập tin này chỉ dành cho mục đích thử nghiệm.
#include "head.h"
int chính() {
func(5, (uint32_t)5, (size_t)5, 0);
trả về 0;
}
Những gì tôi thấy là một trường hợp kỳ lạ:
- Nếu tôi bao gồm
linux/videodev2.h
Chỉ trong các tệp .h,uint32_t
Tệp .cpp không thể truy cập nội dung khác được xác định trong tiêu đề này. (Lỗi tôi nhận được là: uint32_t không được khai báo trong phạm vi này
Và uint32_t không đặt tên loại
Chờ đợi). Mặc dù dòng đầu tiên của tệp .h là #include
Điều này cũng xảy ra.
- Nếu tôi đưa tiêu đề videodev2 vào cả hai tệp cpp,chỉ mộtNó chỉ hoạt động khi tôi nhập nó (videodev2) trước tệp .h.
- Nếu tôi sử dụng
func(5, (uint32_t)5, (size_t)5, (abc*)0);
Trong tệp main.cpp tôi gặp lỗi nói rằng abc không được khai báo trong phạm vi này.
Tôi đang sử dụng lệnh sau để biên dịch:g++ main.cpp head.cpp
Tôi không thể hiểu tại sao. Tôi muốn đưa tiêu đề videodev2 vào tệp .h vì mã sử dụng tệp .h gần như chắc chắn sẽ phụ thuộc vào nó. Nhưng có vẻ như việc đưa nó vào tệp .h chẳng có tác dụng gì cả.
Tôi phải thành thật ở đây. Đây là mã C mà tôi phải chuyển đổi sang C++. Tôi biết tôi không đáp ứng được các tiêu chuẩn và thông lệ tốt nhất. Nhưng tại sao hành vi này lại xảy ra?
Xin hãy nhớ,#bao gồm
Chỉ thị chỉ ra cho bộ tiền xử lý rằng nội dung của tệp đã chỉ định phải được xử lý như thể chúng xuất hiện trực tiếp trong tệp nguồn chứ không phải dưới dạng một lệnh (được diễn giải từ MSDN ).
Với suy nghĩ này, có vẻ như bạn đã gặp phải #bao gồm
không đúng thứ tự và bị thiếu #bao gồm
vấn đề. Tôi đoán là bạn đã không đưa tệp tiêu đề của riêng mình vào tệp .cpp. Điều này có thể giải thích trường hợp một và ba. Hãy xem xét các tài liệu sau:
// tiêu đề.h
// #include <- Tùy chọn 1
hạng A {
void func(uint32_t var);
};
// tiêu đề.cpp
void A::func(uint32_t var) {
// thực hiện
}
// main.cpp
// #include <- Tùy chọn 2
#include "header.h"
// #include <- Tùy chọn 3
int chính() {
// triển khai; một cái gì đó tạo ra một thể hiện của A và gọi func
}
Bây giờ, phương án 1 là không hẳn là mong muốn ;Tốt nhất nên tránh sử dụng trong các tệp tiêu đề #bao gồm
, vì chúng làm tăng thời gian xây dựng và tạo ra các phần phụ thuộc không mong muốn. Tuy nhiên, nó sẽ đảm bảo tiêu đề.h
Loại được yêu cầu có sẵn để sử dụng. Điểm quan trọng là linux/videodev2.h
Nội dung phải xuất hiện trong tiêu đề.h
trước nội dung củatiêu đề.h
Đúng #bao gồm
d.
Điều này đưa tôi đến lựa chọn 2. Tùy chọn 2 cũng biên dịch chính xác vì linux/videodev2.h
được bao gồm trước tiêu đề của bạn và tiêu đề của bạn phụ thuộc vào loại được xác định trong đó. Nó cũng quan trọng để chính.cpp
Và tiêu đề.cpp
Tất cả phải #include "header.h"
, bởi vì chúng đề cập đến các ký hiệu được khai báo bên trong chúng.
Nếu bạn chọn tùy chọn 3, bạn sẽ nhận được loại không xác định uint32_t
lỗi biên dịch và trình biên dịch sẽ trỏ đến tệp tiêu đề của bạn. Điều này là do nội dung của tệp tiêu đề xuất hiện tronglinux/videodev2.h
trước nội dung, do đó trình biên dịch gặp phảiuint32_t
Tôi vẫn không hiểuuint32_t
loại gì
Vì vậy, với tất cả những điều này, bạn có một lựa chọn: bao gồm "linux/videodev2.h" trước mỗi phần bao gồm tiêu đề của riêng bạn hoặc đưa nó trực tiếp vào tiêu đề của bạn. Tôi đã đề cập trước đó rằng cách thứ hai không phải là cách thực hành tốt, nhưng đối với trường hợp cụ thể của bạn, nó có thể là lựa chọn tốt hơn cho cả hai, trong trường hợp các tệp tiêu đề của bạn cần được đưa vào nhiều .cpps.
Tôi nghĩ đó là một sự lặn sâu tiêu đề được biên dịch trước Những cơ hội tốt, nhưng tôi không rành về chúng nên tôi sẽ để người có nhiều kinh nghiệm hơn giải thích chúng.
Hy vọng điều này sẽ giúp :)
Tôi là một lập trình viên xuất sắc, rất giỏi!