Dependency Loop seems unavoidable

T

Tim

Dear All,

Dependency should be not looped. However, I think it unavoidable. For
example, I have two classes: Bank and People as follows

class Bank
{
private:
Set<people*> m_clients; //all clients
};

class People
{
private:
Bank* m_bank; // in which an account is opened.
};

Any way to avoid the dependency loop?

Thanks,

Tim
 
M

meagar

Dear All,

Dependency should be not looped. However, I think it unavoidable. For
example, I have two classes: Bank and People as follows

class Bank
{
private:
Set<people*> m_clients; //all clients

};

class People
{
private:
Bank* m_bank; // in which an account is opened.

};

Any way to avoid the dependency loop?

Thanks,

Tim

You could try rethinking your mapping of real-world objects to
classes; all banks have clients, but not all people have banks?

class Person {
// name, address, etc
};

class Bank {
public:
class Client : public Person {
Bank* m_bank;
// A set of bank account numbers, other client-specific
things that not all people have
};

std::set<Client*> m_clients;
};
 
I

Ian Collins

Tim said:
Dear All,

Dependency should be not looped. However, I think it unavoidable. For
example, I have two classes: Bank and People as follows
class People;
class Bank
{
private:
Set<people*> m_clients; //all clients

Set said:
};

class People
{
private:
Bank* m_bank; // in which an account is opened.
};

Any way to avoid the dependency loop?
There isn't one, provided you don't attempt to dereference a People*
before the full class declaration.
 
J

Jim Langston

Tim said:
Dear All,

Dependency should be not looped. However, I think it unavoidable. For
example, I have two classes: Bank and People as follows

class Bank
{
private:
Set<people*> m_clients; //all clients
};

class People
{
private:
Bank* m_bank; // in which an account is opened.
};

Any way to avoid the dependency loop?

Well, since Bank* inside People is a pointer, the only thing it needs to
compile is a
class Bank;
declaration. It does not need to see the interworkings of Bank unless you
attempt to derefernce it inside of the People class. If People simply
returns the pointer to something, then you have no problem.

Consider, also, that some people use more than one Bank. It depends on what
you are attempting to do.
 
I

Ian Collins

Jim said:
Well, since Bank* inside People is a pointer, the only thing it needs to
compile is a
class Bank;
declaration. It does not need to see the interworkings of Bank unless you
attempt to derefernce it inside of the People class. If People simply
returns the pointer to something, then you have no problem.
I think you have that the wrong way round, it is People that requires a
forward declarations.
 
T

Tim

Well, since Bank* inside People is a pointer, the only thing it needs to
compile is a
class Bank;
declaration. It does not need to see the interworkings of Bank unless you
attempt to derefernce it inside of the People class. If People simply
returns the pointer to something, then you have no problem.

Consider, also, that some people use more than one Bank. It depends on what
you are attempting to do.- Hide quoted text -

- Show quoted text -

It is easy to avoid the compilation loop. I am talking about the
design, the acyclic design.

Thanks.
 
J

Juha Nieminen

Tim said:
It is easy to avoid the compilation loop. I am talking about the
design, the acyclic design.

Why do you want to avoid the dependency loop?

There are cases where a class even has a dependency loop with
itself. A list element is a typical example.
 
J

Jim Langston

Tim said:
It is easy to avoid the compilation loop. I am talking about the
design, the acyclic design.

Again, it depends on what you are trying to do. Are you writing code for a
bank, for people, or for the IRS?

If you are writing code for a bank, then it shouldn't be your concern what
other banks that person uses.

If you are writing code for a person, then it shouldn't be your concern what
other people that bank uses.

If you are writing code for the IRS, it would most likely be in differnet
applicatoins.

What are you trying to accomplish? What is your program intended to do? If
this is just a learning experience, then imo most times you don't need to do
such things except in experimentation.
 
B

BobR

Tim said:
Dear All,
Dependency should be not looped. However, I think it unavoidable. For
example, I have two classes: Bank and People as follows

class Bank{
private:
Set<people*> m_clients; file://all clients
};

class People{
private:
Bank* m_bank; // in which an account is opened.
};

Any way to avoid the dependency loop?
Thanks,
Tim

<G>
Why on earth would you want to put people in a bank?
(after you get their money, you don't want them in the bank! <G>).

class Account{
std::string bankname;
std::string username;
std::string accountnumber;
long long balance; // in pennies
};

class People{
Account account;
};

class Bank{
Set<Account> clients;
public:
Account NewAccount( std::string const &name, long amount );
};
 
V

Victor Bazarov

BobR said:
<G>
Why on earth would you want to put people in a bank?
(after you get their money, you don't want them in the bank! <G>).

He didn't put people in the bank, he put *pointers to people* in it.
You know, like an address book stored in the vault... :)

V
 
B

BobR

Victor Bazarov said:
He didn't put people in the bank, he put *pointers to people* in it.
You know, like an address book stored in the vault... :)

Or a bunch of bank employees standing around pointing at the customers. :-}
( it's not polite to point! <G>)

Hate to jump back to 'serious', but,

.... if the 'Set' was std::set, we both know there's a missing 'comparator'
in the instantiation.
IMHO, a std::vector would be a better choice for pointers. You'd still need
to write some kind of 'unique' to sort it out.

[ caution: I have not finished my first cup of coffee yet! My
single-brain-cell is only about 20% active. <G>]
 
V

Victor Bazarov

BobR said:
Victor Bazarov said:
BobR said:
[..]
Set<people*> m_clients; file://all clients

... if the 'Set' was std::set, we both know there's a missing
'comparator' in the instantiation.

Why do you say that it's missing? There is the default compare
functor, std::less...
IMHO, a std::vector would be a better choice for pointers. You'd
still need to write some kind of 'unique' to sort it out.

8-O why bother with the vector and making it unique and sorting,
when there is std::set for it?
[ caution: I have not finished my first cup of coffee yet! My
single-brain-cell is only about 20% active. <G>]

Figures...

V
 
B

BobR

Victor Bazarov said:
BobR said:
Victor Bazarov said:
BobR wrote:
[..]
Set<people*> m_clients; file://all clients

... if the 'Set' was std::set, we both know there's a missing
'comparator' in the instantiation.

Why do you say that it's missing? There is the default compare
functor, std::less...

Ah, I wasn't aware that (default) std::less was smart enough to dereference
the pointer.
I'll have to read-up on that.

Person joe("Joe Smith");
Person smith("Joe Smith");
std::set<Person*> clients;
clients.insert( &joe );
clients.insert( &smith );
assert( 1 == clients.size() );

?
 
V

Victor Bazarov

BobR said:
Victor Bazarov said:
BobR said:
BobR wrote:
[..]
Set<people*> m_clients; file://all clients

... if the 'Set' was std::set, we both know there's a missing
'comparator' in the instantiation.

Why do you say that it's missing? There is the default compare
functor, std::less...

Ah, I wasn't aware that (default) std::less was smart enough to
dereference the pointer.
I'll have to read-up on that.

It does not dereference it (why would it?), it just compares
the values. The idea for the 'set' is that the uniqueness is
ensured by the strict weak ordering.
Person joe("Joe Smith");
Person smith("Joe Smith");
std::set<Person*> clients;
clients.insert( &joe );
clients.insert( &smith );
assert( 1 == clients.size() );

?

The assertion will fail. 'joe' and 'smith' are different objects.
Their addresses are different, therefore the set will store both
of them, independently.

V
 

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

Staff online

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top