2009-12-03 35 views
19

Vì vậy, tôi có một lớp A, nơi tôi muốn gọi một số chức năng lớp B. Vì vậy, tôi bao gồm "b.h". Nhưng, trong lớp B, tôi muốn gọi một hàm lớp A. Nếu tôi bao gồm "a.h", nó kết thúc trong một vòng lặp vô hạn, phải không? Tôi có thể làm gì với nó?hai lớp có thể nhìn thấy nhau bằng C++ không?

Trả lời

26

Mỗi lớp (A và B) phải có tệp tiêu đề và tệp triển khai.

Mỗi tập tin tiêu đề (ví dụ như A.h) không nên bao gồm các tập tin tiêu đề khác (ví dụ B.h) nhưng có thể bao gồm một tham chiếu về phía trước để các lớp khác (ví dụ như một tuyên bố như class B;), và sau đó có thể sử dụng con trỏ và/hoặc tham chiếu đến lớp khác trong khai báo của nó (ví dụ: class A có thể chứa một thành viên dữ liệu B* và/hoặc làm tham số phương thức).

Mỗi tệp CPP (ví dụ: A.cpp) có thể bao gồm nhiều tệp tiêu đề (ví dụ: A.hB.h). Chúng tôi khuyên mỗi tệp CPP nên bao gồm tệp tiêu đề của chính nó trước tiên (ví dụ: A.cpp phải bao gồm A.h và sau đó B.h, trong khi B.cpp phải bao gồm B.h và sau đó A.h).

Mỗi tệp tiêu đề chỉ nên chứa khai báo chứ không phải định nghĩa của lớp: ví dụ: nó sẽ liệt kê chữ ký của các phương thức của lớp, chứ không phải là các phương thức/triển khai phương thức. tệp .cpp, không có trong tệp tiêu đề). Bởi vì các tệp tiêu đề không chứa chi tiết triển khai, do đó chúng không phụ thuộc vào (không cần phải xem) chi tiết của các lớp khác; nhiều nhất họ cần phải biết rằng, ví dụ, B là tên của một lớp: mà nó có thể lấy từ một tờ khai chuyển tiếp, thay vì bao gồm một tệp tiêu đề trong một tệp tiêu đề khác.

35

Chỉ đặt các khai báo hàm thành viên trong các tệp tiêu đề (.h) và đặt định nghĩa hàm thành viên vào tệp thực thi (.cpp). Sau đó, các tệp tiêu đề của bạn không cần bao gồm lẫn nhau và bạn có thể bao gồm cả hai tiêu đề trong tệp triển khai.

Đối với trường hợp khi bạn cần phải tham khảo các lớp khác trong chữ ký thành viên là tốt, bạn có thể sử dụng một tờ khai chuyển tiếp:

class A; 

này cho phép bạn sử dụng con trỏ và tham khảo các loại (A*A&), mặc dù không A. Nó cũng không cho phép bạn gọi các thành viên.

Ví dụ:

// a.h 
struct B; // forward declaration 

struct A { 
    void foo(B* b); // pointers and references to forward-declared classes are ok 
}; 


// b.h 
struct A; // forward declaration 

struct B { 
    void bar(A& a); // pointers and references to forward-declared classes are ok 
}; 


// a.cpp 
#include "a.h" 
#include "b.h" 

void A::foo(B* b) { 
    b->bar(*this); // full declaration of B visible, ok to call members now 
} 


// b.cpp 
#include "a.h" 
#include "b.h" 

void B::bar(A& a) { 
    a.foo(this); // full declaration of A visible, ok to call members now 
} 
-7

Thử đặt #ifndef, #define#endif xung quanh tệp .h của bạn.

+1

Bài đăng này không trả lời câu hỏi .. –

Các vấn đề liên quan