"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