Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutually recursive classes

How do I implement mutually recursive classes in C++? Something like:

/*
 * Recursion.h
 *
 */

#ifndef RECURSION_H_
#define RECURSION_H_

class Class1
{
  Class2* Class2_ptr;
public:
  void Class1_method()
  {
      //...
      (*Class2_ptr).Class2_method();
      //...
  }
};

class Class2
{
    Class1* Class1_ptr;
public:
    void Class2_method()
    {
        //...
        (*Class1_ptr).Class1_method();
        //...
    };
};


#endif /* RECURSION_H_ */
like image 841
user383352 Avatar asked Aug 04 '10 23:08

user383352


People also ask

What is mutual recursion?

From Wikipedia, the free encyclopedia In mathematics and computer science, mutual recursion is a form of recursion where two mathematical or computational objects, such as functions or datatypes, are defined in terms of each other.

What happens when you have two mutually recursive functions in Python?

If you have two mutually-recursive functions that both alter the state of an object, try to move almost all the functionality into just one of the functions. Otherwise you will probably end up duplicating code. Mutual recursion is also known as indirect recursion, by contrast with direct recursion, where a single function calls itself directly.

Is it possible to have mutually recursive modules in a package?

Once you have mutually recursive modules in a package, you will no longer be able to put modules of an import cycle into different packages, because mutually recursive packages are not supported. The Haskell 98 report says, that Haskell 98 allows mutually recursive modules, but not all compilers support them completely or even in a simple way.

What is an example of a mutually recursive algorithm?

Just as algorithms on recursive data types can naturally be given by recursive functions, algorithms on mutually recursive data structures can be naturally given by mutually recursive functions. Common examples include algorithms on trees, and recursive descent parsers.


4 Answers

  1. Forward-declare the classes (you could get away with forward-declaring only one of them, but for good form do both).
  2. Forward-declare the methods (ditto).
class Class1;
class Class2;

class Class1
{
  Class2* Class2_ptr;
public:
  void Class1_method();
};

class Class2
{
  Class1* Class1_ptr;
public:
  void Class2_method();
};

void Class1::Class1_method()
{
  //...
  (*Class2_ptr).Class2_method();
  //...
}

void Class2::Class2_method()
{
  //...
  (*Class1_ptr).Class1_method();
  //...
}
like image 118
Beta Avatar answered Sep 22 '22 00:09

Beta


Use forward declaration.

class Class2;

class Class1
{
  Class2* Class2_ptr;
};

class Class2 
{
  Class1* Class1_ptr;
}

Because the methods in Class1 will depend on the actual definition of Class2, method definitions must occur after the Class2 declaration, since you can't use methods from only a forward declaration.

On the other hand, this kind of tight coupling is usually indicative of bad design.

like image 33
Jherico Avatar answered Sep 22 '22 00:09

Jherico


Predeclare one of the classes, for example Class2

#ifndef RECURSION_H_
#define RECURSION_H_
class Class2;
class Class1
{
   Class2* Class2_ptr;
   public:
   void Class1_method()
   {
      //...
      (*Class2_ptr).Class2_method();
      //...
   }
};

class Class2
{
     // ...
}  
like image 30
deinst Avatar answered Sep 23 '22 00:09

deinst


Forward declare one of the classes (or both) on the top, eg.:

class Class2;
class Class1 { ... };

and define the methods after both of the classes are defined (that is, out-of-line):

class Class1
{
 ...
 void Class1_method(); // just declare
 ...
};

class Class2
{
 ...
};

// once definition of Class2 is known, we can define the method of Class1
void Class1::Class1_method()
{
      //...
      (*Class2_ptr).Class2_method();
      //...
}
like image 44
jpalecek Avatar answered Sep 26 '22 00:09

jpalecek