2011-02-11 8 views
27

Tôi đang tìm cách tạo hai lớp, mỗi lớp chứa một đối tượng thuộc loại lớp khác. Tôi có thể làm cái này như thế nào? Nếu tôi không thể làm điều này, có một công việc xung quanh, giống như việc mỗi lớp có chứa một con trỏ cho loại lớp khác không? Cảm ơn!Làm thế nào để tạo hai lớp trong C++ sử dụng lẫn nhau làm dữ liệu?

Dưới đây là những gì tôi có:

File: bar.h

#ifndef BAR_H 
#define BAR_H 
#include "foo.h" 
class bar { 
public: 
    foo getFoo(); 
protected: 
    foo f; 
}; 
#endif 

File: foo.h

#ifndef FOO_H 
#define FOO_H 
#include "bar.h" 
class foo { 
public: 
    bar getBar(); 
protected: 
    bar b; 
}; 
#endif 

File: main.cpp

#include "foo.h" 
#include "bar.h" 

int 
main (int argc, char **argv) 
{ 
    foo myFoo; 
    bar myBar; 
} 

$ g ++ main.cpp

In file included from foo.h:3, 
       from main.cpp:1: 
bar.h:6: error: ‘foo’ does not name a type 
bar.h:8: error: ‘foo’ does not name a type 

Trả lời

72

Bạn không thể có hai lớp học trực tiếp chứa các đối tượng của các loại khác, vì nếu không bạn sẽ cần nhiều không gian vô hạn cho các đối tượng (kể từ foo có quán bar mà có một foo có một thanh mà vv)

Bạn thực sự có thể làm điều này bằng cách có hai lớp lưu trữ con trỏ với nhau, mặc dù. Để làm điều này, bạn sẽ cần phải sử dụng tờ khai chuyển tiếp vì vậy mà hai lớp biết về sự tồn tại của nhau:

#ifndef BAR_H 
#define BAR_H 

class foo; // Say foo exists without defining it. 

class bar { 
public: 
    foo* getFoo(); 
protected: 
    foo* f; 
}; 
#endif 

#ifndef FOO_H 
#define FOO_H 

class bar; // Say bar exists without defining it. 

class foo { 
public: 
    bar* getBar(); 
protected: 
    bar* f; 
}; 
#endif 

Chú ý rằng hai tiêu đề không bao gồm từng khác. Thay vào đó, họ chỉ biết sự tồn tại của lớp khác thông qua các tờ khai chuyển tiếp. Sau đó, trong các tệp .cpp cho hai lớp này, bạn có thể #include tiêu đề khác để nhận thông tin đầy đủ về lớp. Các khai báo chuyển tiếp này cho phép bạn phá vỡ chu kỳ tham chiếu của "thanh nhu cầu foo cần foo cần thanh".

+8

"foo cần thanh cần nhu cầu foo bar." lawl. = P – prolink007

3

Điều đó không có ý nghĩa. Nếu A chứa B, và B chứa A, nó sẽ là kích thước vô hạn. Hãy tưởng tượng đặt hai hộp và cố gắng đặt cả hai vào nhau. Không hoạt động, phải không?

Pointers làm việc mặc dù:

#ifndef FOO_H 
#define FOO_H 

// Forward declaration so the compiler knows what bar is 
class bar; 

class foo { 
public: 
    bar *getBar(); 
protected: 
    bar *b; 
}; 
#endif 
+9

Tôi thấy nó hoạt động trên Futurama! –