communicating with every object of the class

L

lou zion

hey all,

i've got a class that A that has a static class member

static int MajorMode;

it's important that if one instance of the class changes this variable, all
instances react immediately. while they'll all see the new value of the
variable, how do you get them each to execute a function when MajorMode
changes?

thanks -- lou
 
A

Andre Kostur

hey all,

i've got a class that A that has a static class member

static int MajorMode;

it's important that if one instance of the class changes this
variable, all instances react immediately. while they'll all see the
new value of the variable, how do you get them each to execute a
function when MajorMode changes?

You'd have to define what "react immediately" means. I suppose one
Standards-friendly way to implement what I think you want:

1) Have some static factory methods for creating instances of the object.
These instances are stored in some sort of container.
2) Have a static method for modifying MajorMode.
3) When that static method is invoked, that method can then iterate over
the container of objects and invoke some function on each instance.
4) Have some static sink methods for destroying instances of the object.
This would also be responsible for removing the instances from the
aforementioned container.
 
J

Jim Langston

lou zion said:
hey all,

i've got a class that A that has a static class member

static int MajorMode;

it's important that if one instance of the class changes this variable,
all instances react immediately. while they'll all see the new value of
the variable, how do you get them each to execute a function when
MajorMode changes?

thanks -- lou

That's where wrappers come in. MajorMode should be private, and anything
that changes it should have to go through interfaces, SetMajorMode or
GetMajorMode.

In your case SetMajorMode would need to, somehow, call a function on each
instance of your class. How you do that is the quandry. If all your
instances are in a vector, pass a reference to the vector to SetMajorMode.
Otherways would be to somehow keep references to each instance of your class
in a static vector, somehow, and iterate through that. Then you would only
create your class through a factory that also added a reference to the
vector. Of course it would need to remove the reference when the class was
deleted.

This seems like a major pain, so I think you need to decide if this is
absolutely neccessary.

What does each instance of the class have to do when MajorMode changes?
Can't each instance do the update the next time one of their functions are
called? If so, I would keep a non static variable int LastMajorMode inside
the class and compare it with MajorMode in calls. If it has changed, do
whatever updates you need to. The drawback of this approach is the
comparison of the two ints. I don't think that would actually take much
time though.
 
B

benben

1) Have some static factory methods for creating instances of the object.
These instances are stored in some sort of container.

The object can register itself within the constructor. So no need using
a factory.
2) Have a static method for modifying MajorMode.
3) When that static method is invoked, that method can then iterate over
the container of objects and invoke some function on each instance.
4) Have some static sink methods for destroying instances of the object.

Again, the object can unplug itself within the destructor.

Ben
 
J

Jim Langston

benben said:
The object can register itself within the constructor. So no need using a
factory.


Again, the object can unplug itself within the destructor.

Ben

Please explain how you would do this? Would you require the constructor to
be passed a reference to the registration list? Or some other way for the
class constructor to find the list?
 
K

Kai-Uwe Bux

Jim said:
Please explain how you would do this? Would you require the constructor
to
be passed a reference to the registration list? Or some other way for the
class constructor to find the list?

What about using a static variable?

#include <set>

class SelfRegister {

typedef std::set< SelfRegister * > Registry;

static Registry the_registry;


void enter ( void ) {
the_registry.insert( this );
}

void leave ( void ) {
the_registry.erase( this );
}

public:

SelfRegister ( void ) {
this->enter();
}

~SelfRegister ( void ) {
this->leave();
}

static
Registry::size_type count ( void ) {
return( the_registry.size() );
}

}; //SelfRegister

SelfRegister::Registry SelfRegister::the_registry;

#include <iostream>

int main ( void ) {
SelfRegister a;
std::cout << SelfRegister::count() << '\n';
{
SelfRegister b;
std::cout << SelfRegister::count() << '\n';
}
std::cout << SelfRegister::count() << '\n';
}

In a multithreaded environment, the methods enter() and leave() and, maybe,
count() would need to do some locking.


Best

Kai-Uwe Bux
 
J

Jim Langston

Kai-Uwe Bux said:
What about using a static variable?

#include <set>

class SelfRegister {

typedef std::set< SelfRegister * > Registry;

static Registry the_registry;


void enter ( void ) {
the_registry.insert( this );
}

void leave ( void ) {
the_registry.erase( this );
}

public:

SelfRegister ( void ) {
this->enter();
}

~SelfRegister ( void ) {
this->leave();
}

static
Registry::size_type count ( void ) {
return( the_registry.size() );
}

}; //SelfRegister

SelfRegister::Registry SelfRegister::the_registry;

#include <iostream>

int main ( void ) {
SelfRegister a;
std::cout << SelfRegister::count() << '\n';
{
SelfRegister b;
std::cout << SelfRegister::count() << '\n';
}
std::cout << SelfRegister::count() << '\n';
}

In a multithreaded environment, the methods enter() and leave() and,
maybe,
count() would need to do some locking.


Best

Kai-Uwe Bux

This is interesting, and I like it a lot. One question though, why did you
use this->enter() and this->leave() instead of just enter() and leave()? Is
there some reason for this that I should be aware of, or just a style issue?
 
K

Kai-Uwe Bux

Jim said:
This is interesting, and I like it a lot. One question though, why did
you
use this->enter() and this->leave() instead of just enter() and leave()?
Is there some reason for this that I should be aware of, or just a style
issue?

There is no reason to write this->enter(), except my habits: I am doing
mostly templated stuff, and in that context writing this-> very often helps
to disambiguate things.


Best

Kai-Uwe Bux
 
?

=?iso-8859-1?q?Stephan_Br=F6nnimann?=

Kai-Uwe Bux said:
#include <set>

class SelfRegister {

typedef std::set< SelfRegister * > Registry;

static Registry the_registry;


void enter ( void ) {
the_registry.insert( this );
}

void leave ( void ) {
the_registry.erase( this );
}

public:

SelfRegister ( void ) {
this->enter();
}

~SelfRegister ( void ) {
this->leave();
}

static
Registry::size_type count ( void ) {
return( the_registry.size() );
}

}; //SelfRegister

SelfRegister::Registry SelfRegister::the_registry;

#include <iostream>

int main ( void ) {
SelfRegister a;
std::cout << SelfRegister::count() << '\n';
{
SelfRegister b;
std::cout << SelfRegister::count() << '\n';
}
std::cout << SelfRegister::count() << '\n';

SelfRegister c(a);
std::cout << SelfRegister::count() << '\n';
// Error: expected 2, got 1

You forgot the copy constructor. Either provide it or make it private.
Regards, Stephan
 
K

Kai-Uwe Bux

Stephan said:
SelfRegister c(a);
std::cout << SelfRegister::count() << '\n';
// Error: expected 2, got 1


You forgot the copy constructor. Either provide it or make it private.
Regards, Stephan


Right. Thanks for catching that.

Kai-Uwe Bux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,434
Messages
2,571,689
Members
48,796
Latest member
Greg L.

Latest Threads

Top