2011-10-08 31 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 ++,您会看到一个错误,例如“不完整类型的使用不正确”。