tags:

views:

114

answers:

3

I have a global object "X" and a class "A". I need a function F in A which have the ability to modify the content of X.

For some reason, X cannot be a data member of A (but A can contain some member Y as reference of X), and also, F cannot have any parameter, so I cannot pass X as an parameter into F. (Here A is an dialog and F is a slot without any parameter, such as accept() )

How can I modify X within F if I cannot pass X into it? Is there any way to let A know that "X" is the object it need to modify?? I try to add something such as SetItem to specify X in A, but failed.

+1  A: 

Since X is a global object you should be able to access it from A::F().
For example:

In B.h:

class B
{
public: 
  B(){x=1};
  virtual ~B(){}
  ChangeSomething(){x=2;}
private:
  int x;
};

In main.cpp

#include "A.h"
#include "B.h"

B X;

int main( int argc, const char* argv[] )
{
  A instanceOfA;
  instanceOfA.ModifyGlobalObject();
}

in A.h

#include "B.h"
extern B X;
class A
{
public:
  ModifyGlobalObject(){X.ChangeSomething();}
};

Of course these classes and global variables can be in different files if you include the headers correctly.

fsmc
Sorry I should make it more clear.They are in different source file, for example, "A" is in main.c, and F is in A.c. And I don't want to let A.c to include main.c just because of the global variable X.
Claire Huang
You won't be able to call `ChangeSomething()` since it's a private method of `B`.
Bertrand Marron
The function F = ChangeSomething() is public, so this part is OK.But I don't want to let A.h includes main.c or other headers
Claire Huang
you can type in A.c (at the top of the file after the includes).extern B X; And it should work without any headers. The extern promises that X exists somewhere else and the linker will make it work. However you will still need the class definition to class B, so hopefully you include class B's header file in A.c. Also, its not good practice to include .c files.
fsmc
This also works. I know I shouldn't include .c, that's why I'm looking for another way, thanks :D
Claire Huang
Yes, but including .h is perfectly fine. If your class A is using one of X's methods, and you are putting class A into A.c (and hopefully A.h so you can include it in your main without using a .c include,) then you will definitely need to include the X.h in A.c. This include requirement will exist even with dash-tom-bang's solution.
fsmc
Yes, class "A" has included class "X", I know if it doesn't, A won't recognize X~~ Thanks :)
Claire Huang
A: 

If X is global, you can set it it within the A::F function.

extern X

class A
{
   void F()
   {
        // set the global variable X
        X = someValue;
   }
};
Jeremy Simon
Sorry I should make it more clear.They are in different source file, for example, "A" is in main.c, and F is in A.c. And I don't want to let A.c to include main.c just because of the global variable X.
Claire Huang
+4  A: 

If you don't want F to reference X globally, then you could 'set' it on the object before calling the "worker" method. E.g.

class A
{
public:
   A() : member_x(NULL) { }
   void SetX(X* an_x) { member_x = an_x; }
   void F(); { member_x->Manipulate(); }

private:
   X* member_x;
};

X global_x;
A global_a;

void DoStuff()
{
   global_a.SetX(&global_x);
   global_a.F();
}
dash-tom-bang
That's what I want to do, thanks :D
Claire Huang
What about the constraint that "X cannot be a data member of A"?
Rob Kennedy
A holds x by value, so this does not allow X to modify the object, as required by the OP. The member variable should be changed to be of type X* - but then F() needs to handle the case where the pointer is null, i.e. SetX() has not yet been called.
Gareth Stockwell
@gareth good point; I'd hoped that people would be able to adapt what I presented to their particular needs but I guess some folks love to downvote. I read "X cannot be a data member of A" to mean "the master X cannot be owned by A." Not knowing what X is, it's impossible to know the best decoration; if X is a smart pointer to something else then a copy is perfectly appropriate IMO.
dash-tom-bang
@Claire you're welcome.
dash-tom-bang
@dash-tom-bang: OK, downvote removed. I accept that X *could* be a smart pointer, but this possibility wasn't my first thought on reading the code. In any case 'modify the content of X' implies that X must be held by reference. If X is a smart pointer to some other object of type Y, then holding the smart pointer by value only allows class A to modify the contents of Y, not those of (the original) X.
Gareth Stockwell
@dash-tom-bang: Writing that previous comment, it occurs to me that commenting on your answer would be easier if the variable names for the member variable and for the automatic variable x were not the same.
Gareth Stockwell
@gareth ok, done. Again- I understand your point; my solution was not fully checked and responding to comments hopefully it has been made much better.
dash-tom-bang