Click here to Skip to main content
15,867,594 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
I have some classes like this
C++
class A
{
public:
    B *b;
    C *c;
};

class B
{
};

class C
{
};

I have some global variables, that is used in A, B and C class. I know using global variables is unsuitable for maintenance, so I'm considering converting to local variables. I'm thinking about this
C++
class C;

class B
{
    C *c;
    int local1;
};

class C
{
    B *b;
    int local2;
};

Then in A class, I make the reference like this
C++
b = new B();
c = new C();
c->b = b;
b->c = c;

So in B class a can access local2 variable of C like this
C++
void B::DoSomething()
{
    c->local2 = 0;
}

Similarly, I can access local1 variable from C. This code works, but I'm wondering, is there a better method? I mean, a clearly method to "cross use" these variables without this cross reference?
Of course, the local1 varialbe is "belong to" B, local2 is "belong to" C in its using mean, so I don't want to declare both local1, local2 in one class.
Posted

Your class structure is a little puzzling. It seems to me that the int value(s) really might belong in A and then B and C instances refer to an instance of A (in the constructor). [The value(s) in A should then be private with a 'get' accessor.]

If this is not the case and you really need the structure as described, the C constructor should perhaps accept a reference to a B instance, and B should have a 'set' accessor for its internal value. Both B's and C's internal values should have private (or maybe/arguably protected) access and have set/get accessors. You shouldn't allow public access to these and access them directly from A.
 
Share this answer
 
v2
Comments
thanh_bkhn 28-Jun-13 1:29am    
I really need A to contains B and C. I might replace the direct access to local variable of C from B by a set/get accessor. But I'm worndering is this cross reference structure OK?
Stefan_Lang 28-Jun-13 3:17am    
It's generally a bad idea to build a structure that effectively creates a cyclic dependency. In doing so you destroy the hierarchical structure, and it is no longer clear which class's operations dominate anothers, or which class should or can release it's data structures first when cleaning up. The more functionality you add to either affected class, the more problems you create, because dependencies are unclear.

It's not always possible to entirely avoid cyclic dependencies, but it's always possible to create a hierarchical structure to resolve responsibilities within such a cycle. If you can provide more information about the roles that the classes A, B and C should fulfil, and what those variables are used for, then we might be able to suggest an appropriate solution.
nv3 28-Jun-13 3:20am    
There is no problem with what you call cross reference. The question is: Is local1 really a property of the B object? If yes, then it belongs there (and not in a global variable) and as Harvey said, you should make it private and offer a set/get function to it. If no, then it doesn't make sense to convert your global variable into a member just "avoid globals". Use the class concept for the logical structuring of your data that makes sense.
The decision where a variable belongs shouldn't be based on "ease of access", but on actual association. You didn't specify what these local variables are for, and what property they describe, but at the heart of avoiding global variables is the realization that almost every variable describes some kind of property or state of some kind of object, and therefore should be tied to that object. (and you should create a class for that object if you didn't already)

Accessibility is really only an afterthought. If for instance you have a variable that describes a property of B, and you need to access this information for specific operations in A and C, then pass that property as a function parameter, or provide a method for be to read the value of this property, if A/C already have access to the B object.

There are certainly exceptions to the abovementioned 'rule'. But it really helps if you consider what, exactly, a certain variable describes. OTOH, if the purpose of that local variable cannot be described easily, this may be due to variable reuse; that is another problem entirely, and should be avoided. There is a recent article about why you shouldn't recycle local variables[^], and it applies to global variables as well. Maybe even more so!
 
Share this answer
 
I would recommend creating a separate class to hold the variables.
Access to the variables could be given using methods instead of directly.

You could also make the variables and methods static to avoid having to create an object of the class.
 
Share this answer
 
An alternative would be to keep the variable local in A and pass a reference to B and C in their constructor. Then B and C store the reference and use the same variable. This is closer to a global variable but it is only known between the 3 classes. It would look like that:

C++
class A
{
    B * b;
    C * c;
    int local
};

class B
{
    B(int & loc) : local(loc)
    {
    }
    int & local;
};


And it would be initialized that way in A:
C++
b = new B(local);


If you only need one instance of local, you may consider making it static. In that case you wouldn't need to pass it in the constructor.
 
Share this answer
 
Comments
thanh_bkhn 1-Jul-13 22:28pm    
Thank. I think your solution could help me.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900