Tôi hy vọng một trong các bạn có thể giải thích cho tôi lý do tại sao trình biên dịch yêu cầu tôi xác định lại một mảng có độ dài cố định tĩnh trong đơn vị biên dịch, mặc dù tôi đã làm như vậy trong tệp tiêu đề. Đây là một ví dụ:
Lớp của tôi.h:
#ifndef MYCLASS_H
#defineMYCLASS_H
lớp MyClass {
private:
char tĩnh myPrecomputeTable[256];
}
#endif
Lớp của tôi.cpp
#include "MyClass.h"
char MyClass::myPrecomputeTable[256];
Nếu tôi loại bỏ việc xác định lại trong MyClass.cpp, trình liên kết sẽ cho biết myPrecomputeTable không được xác định. Cú pháp có vẻ dư thừa. Bất cứ ai có thể giải thích cho tôi tại sao trình biên dịch/trình liên kết yêu cầu định nghĩa?
biên tập:
Xin lỗi, tôi đoán là tôi không chắc mình đang bối rối về điều gì. Tôi hiểu khái niệm khai báo/định nghĩa, nó liên quan nhiều hơn đến việc xác định kích thước của mảng mà tôi thấy thú vị. Trong phần định nghĩa và khai báo mình phải xác định kích thước có vẻ dư thừa.
biên tập:
Tôi đã tìm hiểu thêm và hóa ra có nhiều phương pháp về chủ đề này thân thiện với trình biên dịch. Biên dịch:
MyClass.h
lớp MyClass {
char tĩnh myPrecomputeTable[256];
};
MyClass.cpp
char MyClass::myPrecomputeTable[256];
Biên dịch:
MyClass.h
lớp MyClass {
char tĩnh myPrecomputeTable[];
};
MyClass.cpp
char MyClass::myPrecomputeTable[256];
Biên dịch:
MyClass.h
lớp MyClass {
char tĩnh myPrecomputeTable[256];
};
MyClass.cpp
char MyClass::myPrecomputeTable[];
Không biên dịch:
MyClass.h
lớp MyClass {
char tĩnh myPrecomputeTable[512];
};
MyClass.cpp
char MyClass::myPrecomputeTable[256];
Kích thước phải được xác định trong tệp tiêu đề hoặc lớp hoặc cả hai, nhưng trình biên dịch đủ thông minh để ngăn xung đột kích thước.
Trong tiêu đề:
lớp MyClass {
private:
char tĩnh myPrecomputeTable[256];
}
这是一个声明.
Trong .cpp:
char MyClass::myPrecomputeTable[256];
是一个sự định nghĩa.
MỘT tuyên ngôn cung cấp các thuộc tính cơ bản của một biểu tượng: loại và tên của nó.
MỘT sự định nghĩa cung cấp tất cả các chi tiết của ký hiệu đó--nếu đó là một hàm, nó làm gì; nếu là một lớp, nó có những trường và phương thức nào, nếu đó là một biến, thì biến đó được lưu trữ ở đâu;
Thông thường, trình biên dịch chỉ cần có một khai báo cho một cái gì đó để biên dịch một tệp thành một tệp đối tượng, hy vọng rằng trình liên kết có thể tìm thấy định nghĩa từ một tệp khác. Nếu không có tệp nguồn nào định nghĩa một ký hiệu, nhưng nó được khai báo, thì bạn. sẽ gặp lỗi tại thời điểm liên kết phàn nàn về các ký hiệu không xác định.
Một liên kết tốt để hiểu sự khác biệt giữa hai điều này:http://www.cprogramming.com/declare_vs_define.html
Từ tiêu chuẩn:
3.1 Khai báo và định nghĩa [basic.def]
Một khai báo có thể đưa một hoặc nhiều tên vào một đơn vị dịch thuật hoặc khai báo lại các tên được đưa ra bởi các khai báo trước đó. Nếu vậy, khai báo sẽ chỉ định cách giải thích và các thuộc tính của những tên này. Một khai báo cũng có thể có các tác dụng bao gồm:
- một khẳng định tĩnh (Khoản 7),
- kiểm soát việc khởi tạo mẫu (14.7.2),
- việc sử dụng các thuộc tính (Khoản 7) và
- không có gì (trong trường hợp khai báo trống).
Một tuyên bố là một sự định nghĩa trừ khi nó khai báo một hàm mà không chỉ định phần thân của hàm, nó chứa bên ngoài
người chỉ định hoặc một đặc tả liên kết và không một trình khởi tạo cũng không phải một thân hàm, nó khai báo một thành viên dữ liệu tĩnh trong định nghĩa lớp, nó là một khai báo tên lớp, nó là một khai báo opaque-enum, hoặc nó là một khai báo typedef, Một khai báo sử dụng, một khai báo static_assert, một khai báo thuộc tính, an khai báo trống, hoặc một sử dụng chỉ thị.
Tôi là một lập trình viên xuất sắc, rất giỏi!