Surmounting the "Procedural" Class

Hey everybody,

I'm a long-time programmer, but taking my first steps at C++. I have a problem with class declaration in a project with mine.

I have two classes, class1 and class2. Both are instantiated, into variables iClass1 and iClass2 respectively. The problem is that the methods of each class references the variable of the other class, so something like...

1
2
3
4
5
6
7
8
9
class1
{
public:
int variable;
int increment()
     {
     iClass2.variable ++;
     }
};


1
2
3
4
5
6
7
8
9
class2
{
public:
int variable;
int increment()
     {
     iClass1.variable ++;
     }
};


Because of this, I cannot find a place to declare the variables. I can't declare before the classes are written, as the compiler is still procedural and can't instantiate undefined classes. I can't declare after the classes are written, as the compiler can't compile classes with undefined variables.

I tried searching online, but surprisingly found no clear-cut answer for what I imagine is a common problem for anyone using more than 2 classes. I talked an expert friend (yes, I read the sticky before posting :D ), and he told me that I would have to pre-declare the variables, slotting empty memory-space into them, and THEN fill them with classes later.

But I have NO idea how to do that. So without further adieu, I open my mind to your advice and critique :)

With humble gratitude,
Catt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Class1
{
public:
    int variable;
    int increment()
   {
      iClass2.variable ++;
   }
};

class Class2
{
public:
   int variable;
   int increment()
   {
      iClass1.variable ++;
   }
};


You tell it what it is and then the name you'd like to give it.

Not only that you're really getting confused with instantiating a variable and accessing it almost like It's a member of its own.
Last edited on
so would the instances in the increment() method change as well, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Class1
{
public:
    int variable;
    int increment()
   {
      class2.variable ++;
   }
} class1;

class Class2
{
public:
   int variable;
   int increment()
   {
      class1.variable ++;
   }
} class2;
I suggest you use this in your .h header:
1
2
3
4
5
6
7
class Class
{
public:
   int variable;
   void increment();
   Class();
};


And in your .cpp code file:
1
2
3
4
5
6
7
8
Class::Class(): variable(0)
{
}

void Class::increment()
{
   variable++;
}


In main:
1
2
3
4
Class class1();
Class class2();

class1.increment();


If you want to change a value of another class like you have above, you will need to add Class as a data member.
Last edited on
Ah I see what you did, but my example was an extreme simplification. In my actual project, the two classes are so different that they can't be represented as instances of one class. I should have specified, sorry :\
In that case, just rename Class with Class1 and duplicate it again with name Class2.

Do you need 2 classes to be able to access each other? As instances, internal data members or as a "static" like object.
Last edited on
But would the two classes be able to access each other that way? I feel like the class defined first wouldn't be able to "see" the class defined below it.
Exactly, which is why I'm asking which of the ways you would like them to be related/accessible.
Last edited on
Maybe you would like static members?
.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Class1
{
public:
   static int Variable;
   static void Increment();
};

int Class1::Variable = 0;

class Class2
{
public:
   static int Variable;
   static void Increment();
};

int Class2::Variable = 0;


.cpp
1
2
3
4
5
6
7
8
9
void Class1::Increment()
{
   Class2::Variable++;
}

void Class2::Increment()
{
   Class1::Variable++;
}
Oh! Sorry, I missed that. (It's almost midnight here, so forgive my mistakes)

I will need the classes to access each other as instances.

So maybe imagine this scenario...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Dog
{
    public:
    int fullness;
    void lick_owner()
    {
        iOwner.happiness++;
    }
} iDog;

class Owner
{
    public:
    int happiness;
    void feed_dog()
    {
        iDog.fullness++;
    }
} iOwner;


In this case, there could be multiple dogs, all which need to be fed. Haha, I'm pushing the analogy, but yeah... multiple instances of both classes will probably be required.
Last edited on
You kind of need to keep your header declaration and your definition separate if you want to get tricky.

Would passing by reference work with you?

Dog.h
1
2
3
4
5
6
7
8
9
10
#pragma once

class Owner;

class Dog
{
   public:
   int fullness;
   void lick_owner(Owner& owner);
};


Owner.h
1
2
3
4
5
6
7
8
9
10
#pragma once

class Dog;

class Owner
{
   public:
   int happiness;
   void feed_dog(Dog& dog);
};


Dog.cpp
1
2
3
4
5
6
7
#include "Dog.h"
#include "Owner.h"

void Dog::lick_owner(Owner& owner)
{
   owner.happiness++;
}


Owner.cpp
1
2
3
4
5
6
7
#include "Owner.h"
#include "Dog.h"

void Owner::feed_dog(Dog& dog)
{
   dog.fullness++;
}


Or you could statically define one instance each of Dog and Owner.

It's just strange to make one instance be able to access the same exact instance from the other instance. The previously stated alternative would make more sense, but if you're dealing with multiple objects of the same type then the example would be ok.
Last edited on
I get a compiler error saying that Owner is not declared. Probably because it compiles class Dog before class Owner. :\

I need to get some sleep, but if you're still willing to help, I'll be back tomorrow, bright and early. Thank you so much for your help so far! Good night :)
How about forward declaring and using pointers?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Class1.h

#ifndef __CLASS_1
#define __CLASS_1

class Class2;

class Class1
{
     public:

          Class2* iClass2;

          void increment(int i);
};

#endif 


1
2
3
4
5
6
7
8
9
10
11
12
//Class1.cpp

#include "Class1.h"
#include "Class2.h"

void Class1::increment(int i)
{
     if(i < 5) //to avoid infinite loop
     {
          iClass2->increment(i+1);
     }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Class2.h

#ifndef __CLASS_2
#define __CLASS_2

class Class1;

class Class2
{
     public:

          Class1* iClass1;

          void increment(int i);
};

#endif 


1
2
3
4
5
6
7
8
9
10
11
12
//Class2.cpp

#include "Class2.h"
#include "Class1.h"

void Class2::increment(int i)
{
     if(i < 5) //to avoid infinite loop
     {
          iClass1->increment(i+1);
     }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Main.cpp

#include "Class1.h"
#include "Class2.h"

int main()
{
     Class1 class1;
     Class2 class2;

     class2.iClass1 = &class1;
     class1.iClass2 = &class2;

     class1.increment(1); //passing in a number to avoid infinite loop

    return 0;
}
It'll work now. Didn't have a compiler to test with before.

Or using pointers like above, both have their advantages, depending on whether you are dealing with many different instances on the fly or the same one many times.
Last edited on
Woohoo! I got it working!

Thank you both for all your help. I tested both methods, and they both seem to work. I've decided to go with the Shacktar method, as it suits my particular needs better.

Now I just need to figure out how it works. The flow of the program baffles my simple mind ^_^

Thanks again you two!
Sorry I didn't get in on this sooner... Because no one has mentioned that your program design is probably flawed. Whatever it is you are trying to do is probably better done another way...
Topic archived. No new replies allowed.