 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
kupoo Guest
|
Posted: Sun Feb 19, 2006 12:06 pm Post subject: Sychronizing Two Classes Together |
|
|
I have two classes that need to synchronize with each other. That is, I
want to be able to say a = b and b = a. Would the best way to do that
be to have two friend functions that directly mess with the internals of
classes A and B synchronizing one with the other or vice versa? I would
like if I could to have at least a few member functions involved, but I
certainly don't want this:
/* non-friend of class A OR B! */
A& operator=(A& a, B& b) {
a.setFirstMember(b.getFirstMember());
a.setSecondMember(b.getSecondMember());
/* ...ad nauseum */
}
It would be fine if I could do it like b.save(a) and b.load(a), instead
of a = b and b = a, but I'm not sure how to do that right either. If I
made B::save and B::load take an A& as a parameter, then A would need to
be defined as a class previous to the definition of those functions:
class A {
....
};
class B {
void save(A& a);
void load(const A& a);
};
That seems fine and dandy, but for B::save and B::load to save and load
to structure A, they would need to be friends of A. Otherwise I end up
with the endless nightmare parade of getter/setter functions I mentioned
above, that I do not want. But B::save and B::load have to be defined
before A can declare itself a friend of them!
class A {
friend void B::save(A& a);
friend void B::load(A& a);
/* Uh oh, compiler's not going to like this. */
....
};
class B {
void save(A& a);
void load(A& a);
};
So what do I do? What are best practices? What works the best? All I
know is that I have to be able to store the information in an object of
class B into an object of class A, and I have to store the information
in an object of class A into class B.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Mon Feb 20, 2006 9:06 am Post subject: Re: Sychronizing Two Classes Together |
|
|
In article <c5UJf.35165$H71.23503 (AT) newssvr13 (DOT) news.prodigy.com>, kupoo
<nobody (AT) nowhere (DOT) invalid> writes
| Quote: | I have two classes that need to synchronize with each other. That is, I
want to be able to say a = b and b = a. Would the best way to do that
be to have two friend functions that directly mess with the internals of
classes A and B synchronizing one with the other or vice versa? I would
like if I could to have at least a few member functions involved, but I
certainly don't want this:
|
I think that this is an abuse of operator overloading. I would provide
two free functions called synchronise:
void synchronise(A& dest, B const & source);
void synchronise(B& dest, A const & source);
and, if necessary, make both friends of A and B.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Mon Feb 20, 2006 11:06 am Post subject: Re: Sychronizing Two Classes Together |
|
|
kupoo <nobody (AT) nowhere (DOT) invalid> wrote:
| Quote: | made B::save and B::load take an A& as a parameter, then A would need to
be defined as a class previous to the definition of those functions:
class A {
...
};
class B {
void save(A& a);
void load(const A& a);
};
|
class A; // forward declaration
class B
{
public:
void save(A&);
void load (A const &);
};
class A
{
public:
void save(B &);
void load(B const &);
};
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
benben Guest
|
Posted: Mon Feb 20, 2006 11:06 am Post subject: Re: Sychronizing Two Classes Together |
|
|
| Quote: | So what do I do? What are best practices? What works the best? All I
know is that I have to be able to store the information in an object of
class B into an object of class A, and I have to store the information
in an object of class A into class B.
|
Why doesn't the simplest way work?
class A;
class B;
A& operator= (A& a, const B& b);
B& operator= (B& b, const A& a);
class A
{
friend A& operator= (A&, const B&);
friend B& operator= (B&, const A&);
// ...
};
class B
{
friend A& operator= (A&, const B&);
friend B& operator= (B&, const A&);
// ...
};
A& operator= (A& a, const B& b)
{
// ...
}
B& operator= (B& b, const A& a)
{
// ...
}
Regards,
Ben
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kupoo Guest
|
Posted: Tue Feb 21, 2006 1:06 am Post subject: Re: Sychronizing Two Classes Together |
|
|
Waaait! Hold on! I just realized a slight problem with your idea,
Carl. How would B::save store the data into the object of type A?
Would it call A::load on itself? If so, how would A::load load the data
from the object of B? Call B::save on itself?
void B::save(A& a) {
a.load(*this);
}
void A::load(const B& b) {
b.save(*this);
}
There is still something I'm not understanding. Were you suggesting I
do this:
void B::save(A& a) {
a.setFirstMember(getFirstMember());
a.setSecondMember(getSecondMember());
//...ad nauseum...
}
Because that's what I'm trying to avoid doing, without producing too
much coupling. I don't want to have to define 10 identical functions,
one for each member that must be private. Is it just unavoidable?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kupoo Guest
|
Posted: Tue Feb 21, 2006 1:06 am Post subject: Re: Sychronizing Two Classes Together |
|
|
Carl Barron wrote:
| Quote: | class A; // forward declaration
|
*headshakes* Thank you. I had forgotten about forward declarations
entirely. I think I will do it just the way you suggested! There is a
safer way that doesn't expose B to the nasty third party libraries that
A requires, but your way will probably get better marks for low coupling
between hypothetical classes A and B.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Wed Feb 22, 2006 12:06 pm Post subject: Re: Sychronizing Two Classes Together |
|
|
In article <EtsKf.35813$H71.34616 (AT) newssvr13 (DOT) news.prodigy.com>, kupoo
<nobody (AT) nowhere (DOT) invalid> wrote:
| Quote: | Waaait! Hold on! I just realized a slight problem with your idea,
Carl. How would B::save store the data into the object of type A?
Would it call A::load on itself? If so, how would A::load load the data
from the object of B? Call B::save on itself?
void B::save(A& a) {
a.load(*this);
}
void A::load(const B& b) {
b.save(*this);
}
There is still something I'm not understanding. Were you suggesting I
do this:
void B::save(A& a) {
a.setFirstMember(getFirstMember());
a.setSecondMember(getSecondMember());
//...ad nauseum...
}
Because that's what I'm trying to avoid doing, without producing too
much coupling. I don't want to have to define 10 identical functions,
one for each member that must be private. Is it just unavoidable?
You wrote
class A {
...
};
class B {
void save(A& a);
void load(const A& a);
};
|
I suggested how to get this to compile assuming class A would have
similiar functions for B &'s. I know next to nothing about the layout
of class A or class B.
as short example if you rewrite your getters and setters to
overload the same member function name with an additional argument
of the form int_<N> [see below] then you can write load or save
using another small class that calls the setters and getters in reverse
order. A::get_member(int_<N>) gets what you want to store in
B::set_member(x,int_<N>). etc.
template <int N>
struct int_{}; we only need the tag but you could use boost::mpl::int
here.
class B
{
public:
type_1 get_member(int_<1>);
type_2 get_member(int_<2>);
// ...
type_10 get_member(int_<10>);
void set_member(type_1,int_<1>);
// etc.
void save(A &);
//...
};
similiarly for B
template <class A,class B,int N>
struct copy_data
{
static void do_it(A &a,const B &b)
{
int_<N> tag;
a.set_member(b.get_member(tag),tag);
copy_data<A,B,N-1>::do_it(a,b);
}
};
template <class A,class B>
struct copy_data<A,B,0>
{
static void do_it(A &,const B &){}
};
void A::save(B &b)
{
copy_data<A,B,10>(b,*this);
}
looks like what to do.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
johnchx2@yahoo.com Guest
|
Posted: Wed Feb 22, 2006 12:06 pm Post subject: Re: Sychronizing Two Classes Together |
|
|
kupoo wrote:
| Quote: | I don't want to have to define 10 identical functions,
one for each member that must be private. Is it just unavoidable?
|
What you're actually trying to do is to establish a communications
protocol between classes A and B: you want a way for an object of class
B to tell an object of class A everything it needs to know about its
state to allow A to perform "synchronization" (whatever that is). (And
vice versa, of course.)
Once you think about it as a communication protocol question, the next
steps become easier: you need to define a communication format, and
you need send and/or receive operations.
The "format" can be as simple as a struct. Let's say that everything B
needs to know about A to perform synchronization is three values of
type int. So:
class B {
public:
struct State { int i, j, k }; // "format"
State GetState(); // "send" operation
private:
// stuff & stuffing
};
Now an object of class A can call B::GetState() and obtain the
necessary information to "synchronize."
A can do the same in reverse.
Notice that the "format" of the "message" is independent of the actual
representation of B.
However, it is also true that the communication "protocol" does impose
some limits on how much you can independently change A and B...but that
*is* unavoidable. Maintaining backwards compatibility between two
communicating components is never cost-free.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|