2012-01-04 35 views
6

Bất cứ khi nào tôi lập cái gì đó # bao gồm một lớp người dùng định nghĩa, tôi nhận được những lỗi biên dịch luôn trông giống như: main.cpp: undefined reference to Complex::Complex(double, double)lỗi tập tin bao gồm (C++): tài liệu tham khảo không xác định để ______

Tôi đã giảm được vấn đề một thiết lập ba tập tin cực kỳ trần: main.cpp, và ví dụ, Complex.h và Complex.cpp. Tôi vẫn nhận được lỗi tham chiếu không xác định. Tôi đang phát triển trong Code :: Blocks trên Windows nhưng tôi nhận được điều tương tự bằng cách sử dụng g + + trong Ubuntu. Lý do tại sao điều này xảy ra? Tôi đã thử xây dựng Complex.cpp trước main.cpp trong Code :: Blocks, và tôi đã thử g++ main.cpp Complex.cpp nhiều như tôi đã thử chỉ g++ main.cpp. Cùng một lỗi mỗi lần.

/*======== main.cpp ========*/ 
#include "Complex.h" 

int main() 
{ 
    Complex A(1.0, 1.0); 
    return 0; 
} 

/*======== Complex.h ========*/ 
#ifndef _COMPLEX_H 
#define _COMPLEX_H 

class Complex 
{ 
    public: 
    double x, y; 
    Complex(double real, double imag); 
}; 

#endif 

/*======== Complex.cpp ========*/ 
#include "Complex.h" 

Complex::Complex(double real, double imag) 
{ 
    x = real; 
    y = imag; 
} 

ed: bây giờ tôi nhận được các lỗi khác nhau vì vậy tôi phải làm điều gì đó hoàn toàn sai. Sử dụng cùng một mã như trên, tôi nhận được:

main.cpp: in function 'int main()': 
main.cpp:5:5: error: 'Complex' was not declared in this scope 
main.cpp:5:13: error: expected ';' before 'A' 

Điều này thật lạ lùng. Tất cả mọi thứ đã làm việc trước đó khi tôi có lớp trong một tệp .cpp, nhưng đó là "thực hành xấu" vì vậy tôi đã chuyển các định nghĩa lớp của mình thành các tệp .h và lưu giữ tệp .cpp và bây giờ không có gì hoạt động.

+1

Ngoài ra, hãy chắc chắn thêm "-I" vào dòng biên dịch của bạn. Có lẽ ngay cả "-I", nếu các tệp .h của bạn nằm trong cùng một thư mục. – paulsm4

+3

Nó hoạt động cho tôi. Tôi vừa sao chép 'main.cpp',' Complex.h' và 'Complex.cpp', và chạy' g ++ main.cpp Complex.cpp'. Nó tạo ra 'a.out' tốt thôi. – ruakh

+1

Làm việc cho tôi. @ paulsm4: không nên '.' trong đường dẫn mặc định bao gồm? (lưu ý rằng anh ta đang làm '#include" ... "', không phải '#include <...>') –

Trả lời

6

Đó không phải là lỗi biên dịch, đó là lỗi liên kết. Bạn cần đảm bảo liên kết tất cả các đối tượng của bạn với nhau. Bạn có thể làm điều đó theo một vài cách:

g++ main.cpp Complex.cpp 

Nên làm việc tốt (và thực hiện ở đây khi tôi thử với ví dụ của bạn). Bạn cũng có thể làm điều đó trong bước sau:

g++ -c main.cpp 
g++ -c Complex.cpp 
g++ main.o Complex.o 
+0

Trong câu hỏi, nó đã nói "Tôi đã thử' g ++ main.cpp Complex.cpp "' –

+0

@AaronMcDaid, nhưng rõ ràng là không, vì nó sẽ hoạt động. Tôi cho rằng anh ta có thể quá đơn giản hóa ví dụ của mình, nhưng điều đó cũng không giúp anh ta có được câu trả lời đúng. –

+0

Tôi đồng ý. Tôi đã upvoted câu trả lời của bạn vì nó có vẻ rõ ràng phải :-) Tôi cho rằng chúng tôi đang chờ đợi trên các chi tiết của thông báo lỗi chính xác. –

1

Trong khi chúng ta đang còn lại trong bóng tối cho dù đây là mã thực tế (có lẽ không phải là nó hoạt động cho một số người khác), chúng ta hãy nhận xét về mã bản thân một chút ... (điều này sẽ không có bất kỳ ảnh hưởng nào đối với lỗi trình liên kết)

  1. Tên bắt đầu bằng dấu gạch dưới theo sau chữ cái viết hoa, ví dụ: _COMPLEX_H, được dành riêng cho việc thực hiện trình biên dịch C++ và thư viện chuẩn C++. Không sử dụng chúng.
  2. Biến thành viên được thực hiện tốt nhất private. Rất hiếm khi cần phải tạo thành viên dữ liệu thực tế public (đôi khi nó là hợp lý để làm cho các thành viên không hoạt động public, ví dụ: lớp sự kiện nơi người dùng có thể đăng ký gọi lại, nhưng thường hoạt động như chức năng mặc dù chúng là đối tượng kỹ thuật).
  3. Việc khởi tạo được thực hiện tốt nhất trong danh sách bộ khởi tạo thành viên. Đó là, các nhà xây dựng sẽ giống như thế này:

    Complex :: Complex (thực đôi, hình ảnh kép): x (thực), y (IMAG) {}

Cuối cùng , để mạo hiểm, một vài người đoán được điều gì đang xảy ra với mã thực tế gây ra sự cố liên kết:

  1. Nhà xây dựng được định nghĩa là inline. Rõ ràng, điều này sẽ không hoạt động trừ khi định nghĩa có thể nhìn thấy được khi hàm tạo được sử dụng.
  2. Tuyên bố Complex bằng cách nào đó đã biến nó thành một không gian tên chưa đặt tên và do đó định nghĩa xảy ra để xác định một lớp khác với lớp được xem bởi main.cpp.
Các vấn đề liên quan