Please consider the following three simplified files:
student.h:
#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
and main.cpp:
#include "student.h"
int main();
This wouldn't compile giving me
error C2146: syntax error : missing ';' before identifier 'someStudent'
It would produce a lot more errors (even for the correct portions of code) in a more complicated program. I guess the design is wrong: Student
includes Course
and Course
includes Student
. What I want to represent with it is that a student takes several courses and a course has has several students (I use vectors in a full program, avoided them here for simplicity). Any advice how this would be possible?
Thanks in advance, Vlad.
UPDATE:
Thanks for fast replies. Forward declaration of Student
class in Course
class (and removing #include "student.h"
) seems to do the job.
Sorry, I thought it wouldn't matter here, but in fact I am using vectors of const pointers in each of them (since a Student shouldn't be able to control a Course
and a Course
shouldn't be able to control a Student
), as:
vector<const Student* const> students; // in Course class
A header file should be included only when a forward declaration would not do the job. The header file should be so designed that the order of header file inclusion is not important. The header file inclusion mechanism should be tolerant to duplicate header file inclusions.
Such project header files should contain #include statements for the system headers; if the body includes them first, the compiler does not check this.
You make the declarations in a header file, then use the #include directive in every . cpp file or other header file that requires that declaration. The #include directive inserts a copy of the header file directly into the . cpp file prior to compilation.
cpp should include source1. h before including anything else.
This is going circular, as long as you declare someCourse
and someStudent
as non-pointer members of class Student
and Course
respectively (as you've done), because the compiler sees the definition of Student
, it needs to know its size which in turn means, it needs to know the size of its all members, including Course
which is one of them. But to know the size of Course
, it needs to know the size of Student
. That becomes circular.
So you need to break this circle, by declaring at least one of them as pointer. For example, you can do this:
#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
Also note that when you declare pSomeCourse
as pointer of type Course*
, you don't need to include the header file in which Course
is defined. Just forward declaration of the class Course
is enough, as I did in the above code.
The reason why it works because the size of pointer of any class is same, and the compiler need not know the size of the class, in order to know the size of the pointer of the same class. In other words, the compile can know sizeof(Course*)
without even knowing sizeof(Course)
.
In addition to Nawaz answer:
if you want to access members of Course from members of Student, you need to include Course.h in the .cpp - File where you define the methods of Student.
With g++ you'll get an error like "invalid use of incomplete type" otherwise.
If you want to link two classes you will have to use forward declaration and a pointer to an instance of the declared type in one of the class interfaces. Another interface can stay the same as long as it includes declaration of the member variable's type interface.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With