2009-08-15 67 views
13

Trong một dự án tôi có 2 lớp:Thông tư C++ Tiêu đề Bao gồm

// mainw.h

#include "IFr.h" 
... 
class mainw 
{ 
public: 
static IFr ifr; 
static CSize=100; 
... 
}; 

// IFr.h

#include "mainw.h" 
... 
class IFr 
{ 
public float[mainw::CSize]; 
}; 

Nhưng tôi không thể biên dịch mã này, gặp lỗi tại đường dây static IFr ifr;. Loại bao gồm này có bị cấm không?

+1

Tôi giả định rằng nên được mainw :: CSize –

Trả lời

15

là loại cross -bao gồm bị cấm?

Có.

Một công việc xung quanh sẽ là để nói rằng các thành viên ifr của mainw là một tham chiếu hoặc một con trỏ, vì vậy mà một tiền đạo kê khai sẽ làm thay vì bao gồm cả việc kê khai đầy đủ, như:

//#include "IFr.h" //not this 
class IFr; //this instead 
... 
class mainw 
{ 
public: 
static IFr* ifr; //pointer; don't forget to initialize this in mainw.cpp! 
static CSize=100; 
... 
} 

Ngoài , xác định giá trị CSize trong một tệp tiêu đề riêng biệt (để Ifr.h có thể bao gồm tệp tiêu đề khác này thay vì bao gồm mainw.h).

0

Nếu bạn có

#ifndef __MYHEADER_NAME_WHICH_IS_RANDOM_PER_FILE_H 
#define __MYHEADER_NAME_WHICH_IS_RANDOM_PER_FILE_H 
//... Code.. 
#endif 

quấn quanh mã của bạn, sau đó bạn nên sử dụng tốt :)

[EDIT] Mã đánh vần: O: P

+0

Điều đó sẽ không giúp ích trong trường hợp này. – ChrisW

+0

Điều này thực sự sẽ không giúp ích trong trường hợp này - cần phải rõ ràng rằng lớp mainw rõ ràng sẽ cần phải xem bản khai đầy đủ của lớp Ifr trước khi nó có thể biên dịch –

+0

Cả hai đều đúng. Đoán tôi hơi quá nhanh khi kích hoạt :) – cwap

4

Bạn không thể có hai lớp nhúng lẫn nhau theo cách này. Bạn có thể làm cho một trong số họ một con trỏ:

class foo; 

class bar 
{ 
    foo* fooPtr; 
} 

Bạn sẽ phải xây dựng foo và gán nó vào fooPtr trong constructor thanh và miễn phí nó trong destructor - nó chắc chắn là một chút công việc hơn.

Hoặc, trong trường hợp này, là một trong những người nhận xét được đề xuất, hãy tạo mainw :: size a define và đặt nó ở đâu đó phổ biến.

1

Bạn có thể làm đệ quy bao gồm như thế này, nhưng nói chung bạn cũng sẽ cần phải sử dụng một số loại thủ thuật bảo vệ đầu trang - nếu không bộ tiền xử lý sẽ đi vào một đệ quy vô hạn. Điều này sẽ không thực sự giúp bạn giải quyết vấn đề cơ bản của bạn, bởi vì bạn về cơ bản có hai lớp, mỗi trong số đó lẫn nhau đòi hỏi để xem việc kê khai đầy đủ các khác để biên dịch:

class mainw 
{ 
public: 
static IFr ifr; // needs to see the full declaration of the Ifr class in order to know the size 
... 

class IFr 
{ 
public float[mainw::size]; // needs to see the full declaration of mainw in order to know what size is 

Không có vấn đề mà một bạn đặt đầu tiên, nó sẽ không thể biên dịch được vì nó cần phải biết đầy đủ chi tiết của cái kia.

+0

Và vì các chi tiết đầy đủ của lớp khác là cần thiết cho mỗi lớp, một [tờ khai chuyển tiếp] (http://stackoverflow.com/q/553682/1497596) không giúp ích gì. Tuy nhiên, nếu bao gồm tệp cho biết, lớp 'A', chỉ chứa các con trỏ hoặc tham chiếu đến lớp' B', thì một khai báo chuyển tiếp tới lớp 'B' trong lớp' A' có thể làm cho việc biên dịch có thể. – DavidRR

1

Đó là loại bao gồm hình tròn không được phép bởi C++, nhưng điều này sẽ làm việc:

Thay vì bao gồm IFr.h, sử dụng một bản tuyên bố về phía trước.

class IFr; 
class mainw 
{ 
    //... 
}; 

Điều này sẽ làm mainw biên dịch tốt, nhưng tất cả các mã có sử dụng các ifr viên cần bao gồm IFr.h quá.

Điều này chỉ hoạt động vì ifr là thành viên static. Nếu không, trình biên dịch sẽ cần biết kích thước chính xác của ifr.

Ngoài ra, như nhiều người khác đã nói, bạn nên bao gồm các vệ sĩ xung quanh cả hai tiêu đề để tránh các lỗi đến từ việc bao gồm cùng một tiêu đề hai lần.

#ifndef IFR_H 
#define IFR_H 
//... 
#endif 
1

Bạn có thể làm:

// mainw.h 

#include "IFr.h" 
class mainw { 
public: 
    static const size_t CSize=100; 
    static IFr<CSize> ifr; 
... 
}; 

// IFr.h 
template <size_t Sz> 
struct IFr { 
    float sz_[Sz]; 
}; 

Hoặc trong trường hợp CSize cần phải thay đổi trong thời gian chạy sử dụng một giải pháp con trỏ như @ChrisW câu trả lời cho thấy.

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