Reputation:
In the following code, the constructor can only be defined outside the class, or compiler will give errors.
class Student;
class Teacher
{
private:
int num;
string name;
string sex;
string title;
public:
Teacher(Student &s) {
num=s.num ;
name=s.name ;
sex=s.sex ;
}
void display();
};
class Student
{
public:
int num;
string name;
string sex;
float grade;
friend Teacher;
void set_student();
};
void Teacher::display()
{
cout<<num<<" "<<name<<" "<<sex<<endl;
}
void Student::set_student()
{
cin>>num>>name>>sex>>grade;
}
int main()
{
Student s1;
s1.set_student() ;
Teacher t1(s1);
t1.display() ;
return 0;
}
It didn't compile, but if I move the definition of the constructor outside the class, it compiles:
class Teacher
{
public:
Teacher(Student &s);
...
};
Teacher::Teacher(Student &s)
{
num=s.num ;
name=s.name ;
sex=s.sex ;
}
The error is:
floyd.cpp: In constructor 'Teacher::Teacher(Student&)':
floyd.cpp:37:8: error: invalid use of incomplete type 'class Student'
num=s.num ;
^
floyd.cpp:27:7: error: forward declaration of 'class Student'
class Student;
^
floyd.cpp:38:9: error: invalid use of incomplete type 'class Student'
name=s.name ;
^
floyd.cpp:27:7: error: forward declaration of 'class Student'
class Student;
^
floyd.cpp:39:8: error: invalid use of incomplete type 'class Student'
sex=s.sex ;
^
floyd.cpp:27:7: error: forward declaration of 'class Student'
class Student;
Why does this happen?
Upvotes: 2
Views: 96
Reputation: 726499
In order to be able to compile this declaration
Teacher(Student &s);
the compiler needs to know about class Student
only that it exists. Forward declaration
class Student;
successfully fulfills this requirement: it tells the compiler that there is going to be a definition of class Student
at some later point. However, in order to be able to compile this code
Teacher(Student &s) {
num=s.num ;
...
}
the compiler needs to know the content of the Student
class as well. Specifically, it needs to know that Student
has member variable num
. This is not possible until the point of your program where Student
class is fully defined.
There are two ways of addressing this issue:
Teacher
- this is possible because Student
's code does not depend on Teacher
's definition.Upvotes: 4
Reputation: 171117
This is not related to in-class vs. out-of-class at all. It's all the matter of whether the type Student
is complete (= fully defined) when you use it.
You'll get the exact same error if you move the constructor of the definition of Teacher
, but place it above the definition of Student
.
Since the Teacher
constructor accesses member variables of Student
, it needs to see the full definition of Student
. Just switch the order of the class definitions.
Upvotes: 2
Reputation: 6440
Well, the compiler explains it in detail:
floyd.cpp: In constructor 'Teacher::Teacher(Student&)':
floyd.cpp:37:8: error: invalid use of incomplete type 'class Student'
num=s.num ;
On the line 37 the class Student
is incomplete (since by that line you only forwardly declared it), and accessing its members is prohibited.
This may be fixed by placing the code of Student
class above the code of Teacher
class:
class Teacher; // Forward declaration, for the 'friend' line
class Student {..}; // All the code you now have in the Student class
class Teacher {..}; // All the code of Teacher class
Upvotes: 1