2011-06-29 27 views
7

Vì vậy, tôi mong đợi điều này kết thúc là một câu trả lời đơn giản, nhưng tôi đã hack nó một lúc rồi để khắc phục sự cố này. Vì vậy, tôi có một lớp học đặc biệt, Intersection, rằng khi có trong bất kỳ tiêu đề khác mang lại cho tôi:Tiêu đề do người dùng tạo C2061: Lỗi cú pháp: Mã định danh 'classname'

error C2061: syntax error : identifier 'Intersection'

này được tiêu đề Intersection tôi:

#ifndef INTERSECTION_H 
#define INTERSECTION_H 

#include "Coord.h" 
#include "Road.h" 
#include "TrafficLight.h" 

class Intersection { 
private: 
    int id; 
    Coord * midPoint; 
    Road * northRoad; 
    Road * eastRoad; 
    Road * westRoad; 
    Road * southRoad; 
    TrafficLight * trafficLight; 
public: 
    Intersection(int, Coord *, Road *, Road *, Road *, Road *); 
    ~Intersection(); 
    void transitionTrafficLight(); 
    int getId(); 
    Road * getNorthRoad(); 
    Road * getEastRoad(); 
    Road * getWestRoad(); 
    Road * getSouthRoad(); 
    TrafficLight * getTrafficLight(); 
}; 

#endif 

Bây giờ, nếu tôi cố gắng để sử dụng lớp này ở nơi khác, tôi nhận được lỗi. Ví dụ:

#ifndef ROAD_H 
#define ROAD_H 

#include "Coord.h" 
#include "Intersection.h" 
#include <string> 

class Road { 

public: 
    enum LaneCount { TWO_LANE = 2, FOUR_LANE = 4 }; 
    Road(std::string, Coord *, Coord *, LaneCount, Intersection *, Intersection *, int); 
//shortened 

Riêng tại Road constructor (và bất kỳ các lớp khác mà tham khảo Intersection). Tôi không nghĩ rằng đó là một vấn đề cú pháp, vì Coord là một lớp khác, được định nghĩa theo cách tương tự, và trình biên dịch (VS 2008) không phàn nàn về nó. Nó chỉ là Intersection đặc biệt là đem lại cho tôi sự cố này. :/

Tôi đang gắn thẻ bài tập về nhà - đó là nội dung của nó, mặc dù đây chỉ là lỗi mà tôi không thể loại bỏ hơn là một phần của sự cố.

Suy nghĩ?

+2

Dường như bạn cần chuyển tiếp khai báo 'lớp giao lộ;' trong tệp ROAD_H. – GWW

+0

Thú vị. Điều đó dường như đã làm điều đó. Bạn có thể giải thích tại sao nó hoạt động trong khi bao gồm toàn bộ tiêu đề không, và tại sao chỉ có lớp đó dường như có vấn đề? Làm điều đó trong một câu trả lời và tôi sẽ sẵn sàng cung cấp cho bạn kiểm tra. :) – kcoppock

Trả lời

25

Dường như lỗi là bạn có hai tệp tiêu đề tròn bao gồm nhau - intersection.h và road.h. Làm điều này có xu hướng dẫn đến những bất ngờ kỳ lạ trong C++ vì bao gồm cả bảo vệ hoạt động. Ví dụ, giả sử rằng tôi có hai tập tin tiêu đề mà trông như thế này:

// File: A.h 
#ifndef A_Included 
#define A_Included 

#include "B.h" 

class A {}; 

void MyFunction(B argument); 
#endif 

// File: B.h 
#ifndef B_Included 
#define B_Included 

#include "A.h" 

class B {}; 

void MyOtherFunction(A argument); 
#endif 

Bây giờ, nếu tôi cố gắng #include "A.h", sau đó nó mở rộng ra để

// File: A.h 
#ifndef A_Included 
#define A_Included 

#include "B.h" 

class A {}; 

void MyFunction(B argument); 
#endif 

Khi tôi thử mở rộng ra #include "B.h", tôi nhận được thông tin này:

// File: A.h 
#ifndef A_Included 
#define A_Included 

// File: B.h 
#ifndef B_Included 
#define B_Included 

#include "A.h" 

class B {}; 

void MyOtherFunction(A argument); 
#endif 

class A {}; 

void MyFunction(B argument); 
#endif 

Tại thời điểm này, tiền xử lý sẽ lại cố gắng mở rộng ra A.h, dẫn đến điều này:

// File: A.h 
#ifndef A_Included 
#define A_Included 

// File: B.h 
#ifndef B_Included 
#define B_Included 

// File: A.h 
#ifndef A_Included 
#define A_Included 

#include "B.h" 

class A {}; 

void MyFunction(B argument); 
#endif 

class B {}; 

void MyOtherFunction(A argument); 
#endif 

class A {}; 

void MyFunction(B argument); 
#endif 

Bây giờ, chúng ta hãy xem những gì sẽ xảy ra khi chúng tôi giải quyết tất cả các kỳ lạ bao gồm bảo vệ. Lần đầu tiên chúng ta thấy A, nó được mở rộng ra, như trường hợp khi chúng ta mở rộng ra B lần đầu tiên. Tuy nhiên, khi chúng ta thấy A lần thứ hai, nó không được mở rộng ra chút nào. Như vậy, sau khi lấy ra bình luận, chỉ thị tiền xử lý, chúng tôi nhận mã kết quả này:

class B {}; 
void MyOtherFunction(A argument); 
class A {}; 
void MyFunction(B argument); 

Chú ý rằng khi MyOtherFunction được khai báo, A vẫn chưa được công bố, và do đó trình biên dịch báo cáo lỗi.

Để khắc phục điều này, bạn có thể chuyển tiếp-tuyên bố AB trong các tập tin tiêu đề mà cần đến chúng:

// File: A.h 
#ifndef A_Included 
#define A_Included 

class A {}; 
class B; // Forward declaration 

void MyFunction(B argument); 
#endif 

// File: B.h 
#ifndef B_Included 
#define B_Included 

class B {}; 
class A; // Forward declaration 

void MyFunction(B argument); 
#endif 

Bây giờ, không có phụ thuộc tròn hơn. Miễn là bạn #include các tệp tiêu đề thích hợp trong tệp .cpp, bạn sẽ ổn.

Hy vọng điều này sẽ hữu ích!

+0

Chết tiệt! Đây cũng là một câu trả lời tuyệt vời; cảm ơn vì đã đi sâu vào nó. Tôi cực kỳ gỉ tại C++ (được tập trung vào Java), vì vậy đây là một sự bồi dưỡng tốt đẹp. Cảm ơn bạn! – kcoppock

+0

Bạn đã lưu lại ngày của tôi! –

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