Having highly coupled classes without circular dependencies

Hi there,

I'm working on a simulation program, and am having a bit of a design issue.

There is an object in my program called a sensornode, and this is modeled after a real life object (See Wireless Sensor Networks for details.)

A sensornode is a fairly complex thing to simulate, it has a radio component, which is actually a transceiver, and a receiver, a sensor, a processor, a memory, and so on. And these are just the physical parts, it also has a routing algorithm and a algorithms for dealing with the sensed data.

As such, I planned to use a highly coupled set of classes to manage all these different components, which need to communicate. However, try though I might, I can't seem to overcome issues regarding circular dependencies.

Let's look at some simple class headers for clarities sake.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class sensornode{
private:
  /*
   * COMPONENTS
   */
  boost::shared_ptr<radio > m_radio;
  boost::shared_ptr<sensor > m_sensor;
  boost::shared_ptr<router > m_router;
  boost::shared_ptr<processor > m_processor;
public:
  sensornode(double p_xpos, double p_ypos);
  void simulate(double dt);
  
  friend class processor;
};


1
2
3
4
5
6
7
8
9
10
class processor{
private:
  sensornode *m_node;
  boost::shared_ptr< radio > m_radio;
  boost::shared_ptr< sensor > m_sensor;
public:
  processor(sensornode *parent, boost::shared_ptr<radio > p_radio, boost::shared_ptr<sensor > p_sensor);
  void react();
  void update(bool tag, int round);
};


The problem should now be obvious I hope. See the processor needs to know some things about the sensornode (which is essentially a Facade pattern (see GOF for details on the Facade design pattern)), and the sensornode needs to know about the processor, in order to trigger functions in it.

Obviously, when I compile this:
In file included from controller/../model/sensornode.h:11,
                 from controller/../model/network.h:4,
                 from controller/networkController.h:5,
                 from controller/networkController.cc:1:
controller/../model/processor.h:11: error: ISO C++ forbids declaration of ‘sensornode’ with no type

I get errors related to the circular dependencies.

Now, I can try to fiddle around with forward declaration, but I'm not sure it really handles the problem... What is the best way to do this? How can I handle tight coupling in C++?

Oh, and a final note, I let the sensornode pass in its real pointer because I know that if the sensornode gets destructed, all these classes go with it, by design.
Forward declare sensor node in in the processor file, and processor in sensor node (if boost lets you do that with shared pointers). Then, in the corresponding .cpp files, you can include the required .h(pp)s that let you get the function info, etc.
Re - firedraco:

I know that I can do forward declaration -- see this quote from my first post,

Now, I can try to fiddle around with forward declaration, but I'm not sure it really handles the problem... What is the best way to do this? How can I handle tight coupling in C++?


but I'm not sure that this is the appropriate solution. Is it a design issue, which is just manifesting itself in a implementation hack?
I'm rather confident that, following the inclusion model, you'll be able to meet your requirements. The key will be to use forward declarations and storing a pointer or reference (hopefully a boost::shared_ptr counts) to those members. Forward declarations are not enough if the translation unit needs to know the complete type during compilation but a pointer or reference will eliminate the need for the complete type.

Please make an attempt and, if everything doesn't click, consider posting a more specific/comprehensive example.
Last edited on
Obligatory link: http://cplusplus.com/forum/articles/10627/#msg49679


See section 4 (and section 7 if you want inlined functions)
Last edited on
Topic archived. No new replies allowed.