Reputation: 193
I have two classes A and B which are defines as follows:
class A
{
public:
void *connector;
};
class B
{
public:
void *connector1;
void *connector2;
};
To start, let us assume that I create three objects C1, C2 and C3 based on these classes,
A C1;
B C2;
A C3;
And I use the following code to connect them
C1.connector = &C2;
C2.connector1 = &C1;
C2.connector2 = &C3;
C3.connector = &C2;
So at the moment I have this: C1 <-> C2 <-> C3 (first example).
Important: The reason I am using void pointers inside all the classes is because I cannot predict right from the start how the objects will connect. For example,the answer to this question should be valid if I create a fourth object and make these connections (C1 and C2 the same as before):
B C3;
A C4;
C1.connector = &C2;
C2.connector1 = &C1;
C2.connector2 = &C3;
C3.connector1 = &C2;
C3.connector2 = &C4;
C4.connector = &C3;
Which corresponds to this C1 <-> C2 <-> C3 <-> C4 (second example).
I tried and searched everywhere for a simple solution to implement communication between these objects. There are even several questions with the same name but I could not find a similarity between what was asked and respective answers to the problem I am trying to solve. Maybe because I am not approaching this correctly right from the start. Anyway, by communication I mean a simple way that C2 can call a method in C1 and vice versa.
1) I tried to do it with templates but could not figure out how to do it. All classes would be templates and that seamed really contrived and complicated (hard to read, maintain and implement).
2) I tried to use casting of pointers but since I don't know right form the start to which class they connect I could not do it.
Important: Although I cannot warranty the connections I can live very well with the fact that, for example, an object of class B knows exactly the name of the method it will execute in the object connected to its connectors.
To make it clear, let us assume that we introduce a method
int get_value();
in both class A and class B (but the implementation is different in each class). So, in the second example above, C2 may call it on C1 and C3 may call this method on C2. But note that C2 and C3 are objects of the same class.
Ok, now that I explained my problem, I would like to ask for a simple solution for the communication in this problem. For example, a working piece of code that implements the communication between C2 and C1 but also between C3 and C2 (see example 2 above).
To be specific I think an example in which object C2/C3 can call the get_value method in C1/C2, such that C2/C3 can store the value in a private/public variable would be perfect.
I realize that the way I am trying to implement this may not be the best and answers that solve the problem on a different approach are also welcome. But if possible please show me some code and a little explanation because my main target and expertise is not the programming skills.
Thank you very much in advance.
Upvotes: 6
Views: 9999
Reputation: 2985
I don't know your exact needs, but maybe you shall read the observer pattern it may help you. Or if you can maybe you can try to use Qt
it has a nice siganl-slot mechanism.
Upvotes: 1
Reputation: 48605
The typical way to solve this problem is to define an interface class that describes the communication - the functions that can be performed:
// create an interface to communicate with
struct connected
{
virtual ~connected() {} // must have virtual dtor
virtual int get_value() = 0; // pure virtual functions
};
class A
: public connected // implement the connected interface
{
int value;
public:
A(int value = 0): value(value) {}
// implement the connected interface
int get_value() override { return value; }
connected* connector = nullptr;
};
class B
: public connected // implement the connected interface
{
int value;
public:
B(int value = 0): value(value) {}
// implement the connected interface
int get_value() override { return value; }
connected* connector1 = nullptr;
connected* connector2 = nullptr;
};
int main()
{
A C1;
B C2;
A C3;
C1.connector = &C2;
C2.connector1 = &C1;
C2.connector2 = &C3;
C3.connector = &C2;
C2.connector1->get_value(); // use the connected interface
}
This works because both A
and B
are also of type connected
so they only need to care about the fact that they have pointers to other connected
types and they don't need to care if they are A
or B
.
Upvotes: 3
Reputation: 73366
Basically, void* isn't the way to go.
One alternative approach could be to use inhertiance:
class OBJ
{
public:
virtual string getValue()=0;
};
class A : public OBJ
{
public:
OBJ *connector;
string getValue();
};
class B : public OBJ
{
public:
OBJ *connector1;
OBJ *connector2;
string getValue();
};
The objects could then easily "communicate" refering to the common members of the base OBJ class.
C1.connector->getValue();
C1.connector->connector2->getValue();
Upvotes: 5