2011-10-08 86 views
2

請考慮以下三個簡單的文件:
student.h:C++中的一個週期包括

#ifndef STUDENT_H 
#define STUDENT_H 

#include "course.h" 

class Student 
{ 
private: 
    Course someCourse; 
}; 

#endif 

course.h:

#ifndef COURSE_H 
#define COURSE_H 

#include "student.h" 

class Course 
{ 
private: 
    Student someStudent; 
}; 

#endif 

和main.cpp中:

#include "student.h" 
int main(); 


這不會編譯給我
錯誤C2146:語法錯誤:缺少';'之前標識符'someStudent'

它會在更復雜的程序中產生更多的錯誤(即使對於正確的代碼部分)。我猜設計是錯誤的:Student包括CourseCourse包括Student。我想用它代表的是一個學生需要幾門課程,一門課程有幾個學生(我在一個完整的程序中使用矢量,爲了簡單起見,在這裏避免使用它們)。任何意見如何這將是可能的?

在此先感謝弗拉德。

更新: 感謝您的快速回復。在Course類(和刪除#include "student.h"Student類的前向聲明似乎做的工作。 對不起,我認爲這裏沒什麼關係,但實際上我在其中每個都使用了常量指針的向量(因爲學生不應該能夠控制CourseCourse不應該能夠控制Student),如:

vector<const Student* const> students; // in Course class 
+0

[C++中的循環依賴關係]的可能重複(http://stackoverflow.com/questions/4018816/circular-dependency-in-c) – tenfour

回答

10

這是怎麼回事圓形,只要你聲明someCoursesomeStudentStudent類和Course分別(因爲你所做的)的非指針成員,因爲編譯器看到的Student的定義,它需要知道它的這意味着它需要知道其所有成員的大小,包括Course這是其中之一。但要知道Course的大小,它需要知道Student的大小。這變成了循環。

所以你需要打破這個圈子,宣佈至少其中一個爲指針。例如,你可以這樣做:

#ifndef STUDENT_H 
#define STUDENT_H 

//#include "course.h" //commenting out, as it is not needed! 

class Course; //this is called forward declaration 

class Student 
{ 
private: 
    Course *pSomeCourse; //pointer 
}; 

#endif 

另外請注意,當你聲明pSomeCourseCourse*類型的指針,你並不需要在其中Course定義的頭文件。正如我在上面的代碼中所做的那樣,只需向類Course申報即可。

爲什麼它的作品,因爲任何一類指針的大小是一樣的,而編譯器不需要知道類的大小,才能知道同一類的指針大小的原因。換句話說,編譯可以在不知道sizeof(Course)的情況下知道sizeof(Course*)

0

你不能做到這一點,你必須將它們的至少一個轉換爲指針。

1

如果你想鏈接兩個類,你將不得不使用前向聲明和一個指向其中一個類接口聲明類型的實例的指針。只要包含聲明成員變量的類型接口,另一個接口可以保持不變。

course.h:

#ifndef COURSE_H 
#define COURSE_H 


class Student; 
class Course 
{ 
private: 
    Student* someStudent; 
}; 

#endif 

student.h:

#ifndef STUDENT_H 
#define STUDENT_H 

#include "course.h" 

class Student 
{ 
private: 
    Course someCourse; 
}; 

#endif 
3

除了謝里夫回答:

,如果你想從學生的成員訪問過程的成員

,你需要在.cpp文件中包含Course.h,您可以在其中定義Student的方法。

使用g ++,您會看到一個錯誤,例如「不完整類型的使用不正確」。