Class & Template Recursion

Hello cplusplus.com Forums,

I am pretty new to programming and I have been searching for ways to write classes and templates with recursive function and data members:

1
2
3
4
5
6
7
// something like this:
class A {

   int a;
   int b;
   A * myFunction (any_type); // this would be cool to do . . .
}


I'm wanting to wrap up my procedural style functions into OOP with templates so that it can be reused from a header inclusion and an object. This would be helpful in that every function that is dependent on a particular object would belong to the object and have the access restriction that is specific to the class body. If I could do this with a template, then I could try to re-implement a interesting sort routine that rearranges integers into a template that sorts arrays of objects and other types.

My issue is that I have searched around and I have not found a clear example of the technique anywhere, except for this one:



and this I am not understanding this example. I tried to use something similar within a test object that was supposed to demonstrate the effect, but I couldn't get it to work.

I also wanted to do something along the lines of nested classes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class B {
     // arbitrary stuff . . .

  public:
    struct C;
    void aFunctionOfB (any_type);

} objectB;

class B::C {
      // arbitrary stuff . . .

   public:
      C * aFunctionOfC (any_type);
}



C * B::C::aFunctionOfC (any_type) {

   // arbitrary definition . . .

}

void B::aFunctionOfB (any_type) {

   C objectC = *aFunctionOfC (any_type);  // I'm not sure of the syntax . . .
                       /*   so if aFunctionOfC() wasn't  a class member . . .
   C objectC = aFunctionOfC (any_type);   // this works fine, but its a 
                                             non-pointer */
 }


I got the basic ideal from these articles:



working with pointers is easy enough until I start dealing with pointers to objects or object members. I'm really not sure how everything works then. But I'm not able to get a class recursive function to work syntactically with or without a pointer, but those articles I mentioned have a few people saying that the recursive functions that use the local class as their return type (that's what I'm talking about - member functions that use the local class as the return type within the scope of the local class, in case calling it class/template recursion is incorrect. . .) use a pointer for some reason. But in any event, if it allows the flexibility that it seems to provide in with the benefits of OOP, then it's worth learning and will be very useful to me.

Is their anyone who might be willing to direct me to a web link that explains these techniques more thoroughly, or might be able to give an example of both the ideal of using a local class as the return type from within the scope of the local class and/or how to properly nest classes? I hope that I am conveying the right ideal about the nature of my problem, as it might be an important technique to learn, or, as far as I know, there could be a better way to accomplish this. The friend keyword could probably be used, but I've listened to quite a few people that recommend not using friend as it overrides the class access restrictions, so it could produce problem code that malfunctions in a way that's difficult for a novice programmer to root out.

I have spent quite a bit of time searching for "class recursion c++" and other variants of the question. Any help that could be provided will be appreciated, whether I'm smart enough to follow it or not, but I assume many of you are able teachers and qualified to give adequate help to those that come looking for. If I need to give more specific information about the problem, please indicate that and I will try to accommodate you. If I have indicated the wrong problem in my thread title, "Class & Template Recursion," please inform me of the correct concept that I am requesting. Perhaps that is a reason why I am unable to find the answer to this issue.
Last edited on
I did not understand what is your goal. Can you try to explain it more simply?
Last edited on
Nested classes are very simple things. All they do is hide a name inside another namespace, so there's nothing "recursive" about them.

1
2
3
4
5
class X {
public:
  class Y {
  };
};

Instantiating an X does not create a Y inside it. All having the Y inside X does is put it inside X's namespace. That's it. Otherwise it's exactly the same as declaring it outside of X (except for any access restrictions).

1
2
3
4
int main(){
  X x;    // No Y's were created in the making of this X
  X::Y y; // This creates a Y.
}


To have a class contain a data member of its own type you would have to make that member a pointer:

1
2
3
class M {
  M* m;
};

That is a kind of recursion, I guess.

In the future, please keep your questions relatively short and to the point.

In the future, please keep your questions relatively short and to the point.


Yeah, I can do that. Thanks for the feed back.

I did not understand what is your goal. Can you try to explain it more simply?


My problem is dealing with this issue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class A {
     // arbitrary stuff . . .

  public:
    struct B;
    void aFunctionOfA (any_type);

} objectA;

class A::B{
      // arbitrary stuff . . .

   public:
      B * aFunctionOfB (any_type);
}



B * A::B::aFunctionOfB (any_type) {

   // arbitrary definition . . .

}

void A::aFunctionOfA (any_type) {

   B objectB = *aFunctionOfB (any_type);  // I'm not sure of the syntax . . .<- Help Needed Here
                      
 }


You see were it's saying that in the definition of aFunctionOfB() that I'm unsure how to assign it to objectC because its needs to be a pointer? I have done a lot of tinkering and searching but the answer eludes me somehow.

So how do I do operations like this?
Last edited on
You cannot call aFunctionOfB without an object. This is a member function and so you need an object on which to call it (it needs a this pointer). Example:

1
2
3
4
5
void A::aFunctionOfA (any_type)
{
  B foo;
  B bar = *(foo.aFunctionOfB(any_type)); // notice:  "foo."
}


If you don't need a B object for this function (which might be the case if the function does not access any data members of B), then you can make the function static:

1
2
3
4
5
class A::B
{
public:
  static B* aFunctionOfB(any_type);
};


In which case you would need to call it like so:

1
2
3
4
5
void A::aFunctionOfA (any_type)
{
  B foo;
  B bar = *(B::aFunctionOfB(any_type)); // notice:  "B::"
}


I'm also concerned about whether or not this is really the type of function you want. Usually you don't copy objects via a pointer return value like this. If the objective of the function is to set a certain B object, a better approach is to pass a B pointer/reference as a parameter:

1
2
3
4
5
6
7
8
9
10
11
class A::B
{
public:
  static void aFunctionOfB(B* b, any_type);
};

void A::aFunctionOfA (any_type)
{
  B foo;
  B::aFunctionOfB(&foo,any_type);
}


There are a lot of additional complications with returning a pointer (the object it points to must remain in scope -- or if dynamically allocated you need to delete it, etc) -- not to mention doing an assignment like you were requires the object be copied to another object, whereas this method sets the object directly.

But it all depends on the situation.
Thanks Disch, and again, thank you Hammurabi,

with your help I have got the class nesting and class recursion solved:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// class nesting and class recursion
struct A {
   // stuff here thats not important to the point...

	struct B {
	   // stuff here thats not important to the point...
	      B aFunctionOfB (any_type);
        } objectB;  // used in aFunctionOfA()

        void aFunctionOfA (any_type);
} objectA;

A::B A::B::aFunctionOfB (any_type) { 
   // doing percedures on objectB2... 
   return objectB_2;
}

void A::aFunctionOfA (any_type) {
   B objectB_3 = (objectB.aFunctionOfB (any_type));
}


I was focusing on using pointers, which was unnecessary considering that I can avoid using them for my specific tasks, and so the version of the code I have displayed works for the purpose of the needed behavior I intended the program to have.

Disch:
There are a lot of additional complications with returning a pointer... not to mention doing an assignment like you were requires the object be copied to another object, whereas this method sets the object directly


This is interesting and informative, because I am quite functionally illiterate in terms of using pointers in this way at the moment. The above code works, but I will experiment with the static void and static * version to see if I can understand them better. This is very good information and I appreciate your concern.
Last edited on
Topic archived. No new replies allowed.