Hi all,

I'm trying to create two classes which each of them contain a vector of object of the other class. Below is roughly the idea of what I'm trying to do but it seems that it cannot work as it will end up into infinite recursion or something. What options do I have?

Thanks in advance.

class Subject{
    vector<Student> list_of_student;
};

class Student{
    vector<Subject> list_of_subject;
};

Edited 5 Years Ago by jcax: n/a

A vector of pointers?

struct student ;

struct subject
{
   // ...
   std::vector< student* > list_of_students ;
   // ...
};

struct student
{
   // ...
   std::vector< subject* > list_of_subjects ;
   // ...
};

I don't understand. Why this would not work?

class Student;

class Subject{
    vector<Student> list_of_student;
};

class Student{
    vector<Subject> list_of_subject;
};

Edited 5 Years Ago by jcax: n/a

Yes as you figured out you need a forward deceleration :

class Student; //tell compiler that you are going to create a Student class later

class Subject{
    vector<Student> list_of_student;
};

class Student{
    vector<Subject> list_of_subject;
};

Your first attempt doesn't work because the Student class doesn't exist when you declare std::vector<Student>.

But I try to do this and I got error.

class Student; //tell compiler that you are going to create a Student class later

class Subject{
    vector<Student> list_of_student;

    public:
        void addStudent(Student newStudent)
        {
            list_of_student.push_back(newStudent);
        }
};

class Student{
    vector<Subject> list_of_subject;
};

There was an extended debate in the C++ standards committee about whether the standard library should be required to support recursive data structures. The simplest case:

struct T {
    vector<T> vt;
};

There is no technical reason why this should not be possible, but implementing it is quite difficult, and in the end, the committee decided that C++ implementations should not be required to do so.

So if your implementation happens to support the kind of mutual recursion we are discussing here, that's just a stroke of luck; another implementation might not be so generous.

The pointer solution adds memory-management problems, so perhaps some kind of smart pointer class (such as auto_ptr) might be in order. Despite the complexity of such solutions, they are the only way that I can think of to be assured of portability when you want to implement such recursive data structures.

This article has been dead for over six months. Start a new discussion instead.