467,145 Members | 1,083 Online
Bytes | Developer Community
Ask Question

Home New Posts Topics Members FAQ

Post your question to a community of 467,145 developers. It's quick & easy.

circular dependency...

Hi,

I have an issue which is the ordinary and always recurring circular
dependency - but I do not know how to resolve it :-( The usual forward
declaration does not help...

I have a client that uses a resource. As a consequence of using the
resource, the resource later receives an asynchronous notification (from an
underlying layer, e.g. OS). This notification should then be forwarded to
the Client that owns the resource.

In code this looks something:

int main()
{
Resource resource; // Define the resource
Client client(&resource); // Configure the client to own the resource
client.Execute(); // Execute operation, which in turn uses the
resource

RunEventLoopForever();
}
class Resource
{
Client* m_client;
public:
void SetClient(Client* client)
{
m_client = client;
}

void Use()
{
// Use this resource
// DoSomethingInteresting()
}
void AsyncNotification()
{
m_client->Notify();
}
};

class Client
{
Resource* m_resource;
public:
Client(Resource* res) : m_resource(res)
{
m_resource->SetClient(this);
}
void Execute()
{
m_resource->Use();
}
void Notify()
{
// Handle notification
// m_resource->Whatever()
}
};

What should I do to resolve this issue?
Complete redesign? Rather not - I like this simple design (besides it
doesn't work...)
Introducing something in between to break the dependency? If so - what?

Thanks in advamce!
/Rob
Nov 28 '05 #1
  • viewed: 2639
Share:
3 Replies

Rob Clark wrote:
class Resource
{
Client* m_client;
public:
void SetClient(Client* client)
{
m_client = client;
}

void Use()
{
// Use this resource
// DoSomethingInteresting()
}
void AsyncNotification()
{
m_client->Notify();
}
};

class Client
{
Resource* m_resource;
public:
Client(Resource* res) : m_resource(res)
{
m_resource->SetClient(this);
}
void Execute()
{
m_resource->Use();
}
void Notify()
{
// Handle notification
// m_resource->Whatever()
}
};

What should I do to resolve this issue?


Donot define member functions inside the class. Simply declare them.
Define them outside the class. Use inline if you want them to be
inlined. Then simply declare the required class.

//header file Resource.h
class Client;
class Resource
{
Client* m_client;
public:
void SetClient(Client* client);
void Use();
void AsyncNotification();
};

// definitions will go in Resource.cpp. Include Resource.h there.

HTH.

Nov 28 '05 #2
"Rob Clark" <se@ms.com> wrote in message
news:v%***********@nntpserver.swip.net
Hi,

I have an issue which is the ordinary and always recurring circular
dependency - but I do not know how to resolve it :-( The usual
forward declaration does not help...

I have a client that uses a resource. As a consequence of using the
resource, the resource later receives an asynchronous notification
(from an underlying layer, e.g. OS). This notification should then be
forwarded to the Client that owns the resource.

In code this looks something:
Plainly the Resource and Client classes must be declared prior to main(),
quite apart from any circular dependency issues.

int main()
{
Resource resource; // Define the resource
Client client(&resource); // Configure the client to own the
resource client.Execute(); // Execute operation, which in turn
uses the resource

RunEventLoopForever();
}
class Resource
{
Client* m_client;
public:
void SetClient(Client* client)
{
m_client = client;
}

void Use()
{
// Use this resource
// DoSomethingInteresting()
}
void AsyncNotification()
{
m_client->Notify();
}
This is where your fundamental problem lies. You are calling a member
function of Client before the client class has been defined. The solution is
to only declare AsyncNotification here and define it later.
};

class Client
{
Resource* m_resource;
public:
Client(Resource* res) : m_resource(res)
{
m_resource->SetClient(this);
}
void Execute()
{
m_resource->Use();
}
void Notify()
{
// Handle notification
// m_resource->Whatever()
}
};

What should I do to resolve this issue?
Complete redesign? Rather not - I like this simple design (besides it
doesn't work...)
Introducing something in between to break the dependency? If so -
what?
Thanks in advamce!
/Rob


The following compiles:

class Client;

class Resource
{
Client* m_client;
public:
void SetClient(Client* client)
{
m_client = client;
}

void Use()
{
// Use this resource
// DoSomethingInteresting()
}
void AsyncNotification();
};

class Client
{
Resource* m_resource;
public:
Client(Resource* res) : m_resource(res)
{
m_resource->SetClient(this);
}
void Execute()
{
m_resource->Use();
}
void Notify()
{
// Handle notification
// m_resource->Whatever()
}
};

void Resource::AsyncNotification()
{
m_client->Notify();
}
int main()
{
Resource resource; // Define the resource
Client client(&resource); // Configure the client to own the resource
client.Execute(); // Execute operation, which in turn uses the
resource

//RunEventLoopForever();
}
--
John Carson

Nov 28 '05 #3
Oh so obvious when you have the answer - thank you both guys, Neelesh and
John!
/Rob
Nov 28 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Evelyne | last post: by
1 post views Thread by Henry Miller | last post: by
2 posts views Thread by ernesto basc?n pantoja | last post: by
1 post views Thread by ChrisB | last post: by
4 posts views Thread by Henke | last post: by
2 posts views Thread by Rimma Meital via .NET 247 | last post: by
7 posts views Thread by barias@axiscode.com | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.