Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Design question - linked list or std::list

Reply
Thread Tools

Design question - linked list or std::list

 
 
Angus
Guest
Posts: n/a
 
      03-15-2009
Hello

I am modelling a telephone system and I have created a call and a
party class. A call can have one to many parties. For example in a
conference call there can be 3 or more parties. In a call transfer
there can be 3 parties and one of the parties disconnects to transfer
the call.

I need to be able to traverse the list of parties on each call. for
example if each party to the call is disconnected I can remove the
call object.

I create the call object as a pointer and so I delete when the each
party to the call has disconnected. The call object has a std::list
of the party objects. Currently, the list is of party objects, not
pointers to party objects.

I was wondering if it would be better to change the design so that the
std::list is of pointers to party. Or even to have the call object
create party* 's and the party object to be a linked list - ie a means
to SetNextParty(party* next).

But if I implement as a linked list I have the hassle of having to
delete each party. I would do this when the call* was being deleted.

Anyone got any comments on the best approach?

A
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      03-15-2009
* Angus:
> Hello
>
> I am modelling a telephone system and I have created a call and a
> party class. A call can have one to many parties. For example in a
> conference call there can be 3 or more parties. In a call transfer
> there can be 3 parties and one of the parties disconnects to transfer
> the call.
>
> I need to be able to traverse the list of parties on each call. for
> example if each party to the call is disconnected I can remove the
> call object.
>
> I create the call object as a pointer and so I delete when the each
> party to the call has disconnected. The call object has a std::list
> of the party objects. Currently, the list is of party objects, not
> pointers to party objects.
>
> I was wondering if it would be better to change the design so that the
> std::list is of pointers to party. Or even to have the call object
> create party* 's and the party object to be a linked list - ie a means
> to SetNextParty(party* next).
>
> But if I implement as a linked list I have the hassle of having to
> delete each party. I would do this when the call* was being deleted.
>
> Anyone got any comments on the best approach?


Avoid raw pointers. Use boost::shared_ptr and boost::weak_ptr. I did this thing
once, unfortunately as bug-fixing for existing system implemented in Visual
Basic, and it turned you'll end up with circular references, but not more than
can be fixed by proper application of weak pointers.

std::list is good idea in C++.

Try to avoid setters and getters, they're generally in the same class of
features-to-avoid as global variables, indicating redundantly duplicated logic
at caller sites, i.e. that you're missing some crucial abstraction(s).


Cheers & hth.,

- Alf

--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! Just going there is good. Linking
to it is even better! Thanks in advance!
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      03-15-2009
On Mar 15, 1:25 pm, Angus <(E-Mail Removed)> wrote:

> I am modelling a telephone system and I have created a call
> and a party class. A call can have one to many parties. For
> example in a conference call there can be 3 or more parties.
> In a call transfer there can be 3 parties and one of the
> parties disconnects to transfer the call.


> I need to be able to traverse the list of parties on each
> call. for example if each party to the call is disconnected I
> can remove the call object.


> I create the call object as a pointer and so I delete when the
> each party to the call has disconnected. The call object has
> a std::list of the party objects. Currently, the list is of
> party objects, not pointers to party objects.


I'm having trouble with your vocabulary. You don't "create
something as a pointer", you create an object (which probably
isn't a pointer). If your system is anything like the telephone
systems I've worked on, then Party and Call have identity (and
explicit lifetimes), and can't be copied, so all of your
containers would just contain pointers.

The simplest solution would probably be to use std::set for the
parties of a Call, e.g.:

class Call
{
public:
explicit Call( Party* initializingParty )
{
connect( initializingParty ) ;
}

void connect( Party* addedParty )
{
myConnectedParties.insert( addedParty ) ;
}

void disconnect( Party* removedParty )
{
myConnectedParties.erase( removedParty ) ;
if ( myConnectedParties.empty() ) {
delete this ;
}
}

private:
std::set< Party* > myConnectedParty ;
} ;

Of course, you'll need additional logic for other aspects of the
call.

> I was wondering if it would be better to change the design so
> that the std::list is of pointers to party. Or even to have
> the call object create party* 's and the party object to be a
> linked list - ie a means to SetNextParty(party* next).


I can't think of why you'd use a list here. (Given the
typically small size of the set, using std::vector would
probably be more efficient, but it requires more code.) And I
can't quite imagine a case where Party would be copiable, and
could be used in a standard container.

> But if I implement as a linked list I have the hassle of
> having to delete each party. I would do this when the call*
> was being deleted.


You only delete a Party when it becomes unknown to the system.
Not when it disconnects from a call.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      03-15-2009
On Mar 15, 1:32 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> * Angus:
> > I am modelling a telephone system and I have created a call
> > and a party class. A call can have one to many parties.
> > For example in a conference call there can be 3 or more
> > parties. In a call transfer there can be 3 parties and one
> > of the parties disconnects to transfer the call.


> > I need to be able to traverse the list of parties on each
> > call. for example if each party to the call is disconnected
> > I can remove the call object.


> > I create the call object as a pointer and so I delete when
> > the each party to the call has disconnected. The call
> > object has a std::list of the party objects. Currently, the
> > list is of party objects, not pointers to party objects.


> > I was wondering if it would be better to change the design
> > so that the std::list is of pointers to party. Or even to
> > have the call object create party* 's and the party object
> > to be a linked list - ie a means to SetNextParty(party*
> > next).


> > But if I implement as a linked list I have the hassle of
> > having to delete each party. I would do this when the call*
> > was being deleted.


> > Anyone got any comments on the best approach?


> Avoid raw pointers. Use boost::shared_ptr and boost::weak_ptr.
> I did this thing once, unfortunately as bug-fixing for
> existing system implemented in Visual Basic, and it turned
> you'll end up with circular references, but not more than can
> be fixed by proper application of weak pointers.


No. The pointers here are only used for navigation. As you
point out, boost::smart_ptr will only complicate things; using
raw pointers is far simpler, safer and more appropriate.

> std::list is good idea in C++.


Better than implementing your own, but in this case, I'd use
either std::set or std::vector.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      03-15-2009
On Mar 15, 5:37 pm, Jeff Schwab <(E-Mail Removed)> wrote:
> Angus wrote:


> > I create the call object as a pointer and so I delete when
> > the each party to the call has disconnected.


> Why? Why not let a standard collection manage the calls, just
> as a collection manages the parties? Even if a collection
> isn't the right tool, a smart-pointer might be.


Because calls (and parties) are entity objects, and have
explicit lifetimes which have nothing to do with containers (or
pointers) used for navigation, and you can't use containers of
the objects, because they don't support copy. This is a
classical example of a case where he needs raw pointers; smart
pointers just lead to more complicated code.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      03-15-2009
* James Kanze:
> On Mar 15, 1:32 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
>> * Angus:
>>> I am modelling a telephone system and I have created a call
>>> and a party class. A call can have one to many parties.
>>> For example in a conference call there can be 3 or more
>>> parties. In a call transfer there can be 3 parties and one
>>> of the parties disconnects to transfer the call.

>
>>> I need to be able to traverse the list of parties on each
>>> call. for example if each party to the call is disconnected
>>> I can remove the call object.

>
>>> I create the call object as a pointer and so I delete when
>>> the each party to the call has disconnected. The call
>>> object has a std::list of the party objects. Currently, the
>>> list is of party objects, not pointers to party objects.

>
>>> I was wondering if it would be better to change the design
>>> so that the std::list is of pointers to party. Or even to
>>> have the call object create party* 's and the party object
>>> to be a linked list - ie a means to SetNextParty(party*
>>> next).

>
>>> But if I implement as a linked list I have the hassle of
>>> having to delete each party. I would do this when the call*
>>> was being deleted.

>
>>> Anyone got any comments on the best approach?

>
>> Avoid raw pointers. Use boost::shared_ptr and boost::weak_ptr.
>> I did this thing once, unfortunately as bug-fixing for
>> existing system implemented in Visual Basic, and it turned
>> you'll end up with circular references, but not more than can
>> be fixed by proper application of weak pointers.

>
> No. The pointers here are only used for navigation.


You don't know that the pointers are used for navigation. And chances are they
will not be purely navigation. Don't recommend an unsafe alternative just
because you think or wish there's a chance that it might be safe.


> As you
> point out, boost::smart_ptr will only complicate things; using
> raw pointers is far simpler, safer and more appropriate.


I'm sorry, that's wrong.


>> std::list is good idea in C++.

>
> Better than implementing your own, but in this case, I'd use
> either std::set or std::vector.


I was commenting on the OP's info that he's using std::list; I was not making a
freestanding recommendation. There is too little to go on regarding his data
structures, what they are and what they will be, to make a freestanding
recommendation. I know the big layout from work in that domain, but the details
you'd need for making the choice that you're making are not available, so that
recommendation is most likely the opposite of helpful -- your recommendation
is sort of like recommending to someone designing a "vehicle" that it should
have rubber tires, which is helpful only by chance, if it is.


Cheers & hth.,

- Alf

--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! Just going there is good. Linking
to it is even better! Thanks in advance!
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      03-16-2009
On Mar 15, 7:43 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> * James Kanze:
> > On Mar 15, 1:32 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> >> * Angus:


[...]
> >> Avoid raw pointers. Use boost::shared_ptr and boost::weak_ptr.
> >> I did this thing once, unfortunately as bug-fixing for
> >> existing system implemented in Visual Basic, and it turned
> >> you'll end up with circular references, but not more than can
> >> be fixed by proper application of weak pointers.


> > No. The pointers here are only used for navigation.


> You don't know that the pointers are used for navigation.


Actually, I do. Having working in telecoms for a large part of
my career, I have a pretty good idea as to what is needed, and
what isn't.

> And chances are they will not be purely navigation.


In which case, that's the error that needs fixing.

> Don't recommend an unsafe alternative just because you think
> or wish there's a chance that it might be safe.


In this case, it's boost::shared_ptr which would be unsafe, and
likely lead to memory leaks (due to cycles).

> > As you point out, boost::smart_ptr will only complicate
> > things; using raw pointers is far simpler, safer and more
> > appropriate.


> I'm sorry, that's wrong.


No. I've worked on enough different systems to know,
particularly in this domain. Navigation is important, objects
have explicit lifetimes, and boost::shared_ptr is not
appropriate for navigation and objects with explicit lifetimes.

> >> std::list is good idea in C++.


> > Better than implementing your own, but in this case, I'd use
> > either std::set or std::vector.


> I was commenting on the OP's info that he's using std::list; I
> was not making a freestanding recommendation. There is too
> little to go on regarding his data structures, what they are
> and what they will be, to make a freestanding recommendation.


Yes and no. Knowing the domain quite well, I do have quite a
bit to go on. But seriously, you probably know enough about
telephones, and using them, to be able to guess what he's trying
to do (at least at the level he has asked about---call
management is a lot more complicated than that).

> I know the big layout from work in that domain, but the
> details you'd need for making the choice that you're making
> are not available, so that recommendation is most likely the
> opposite of helpful -- your recommendation is sort of like
> recommending to someone designing a "vehicle" that it should
> have rubber tires, which is helpful only by chance, if it is.


A somewhat closer analogy would be that my recommendation is
like recommending to someone designing a "vehicle" that it
should have round wheels.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      03-16-2009
On Mar 15, 8:52 pm, Jeff Schwab <(E-Mail Removed)> wrote:
> James Kanze wrote:
> > delete this ;


> Boo.


Other suggestions. If you have a better alternative, present it
(and explain why it is better).

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
nick_keighley_nospam@hotmail.com
Guest
Posts: n/a
 
      03-16-2009
On 15 Mar, 12:25, Angus <(E-Mail Removed)> wrote:

> I am modelling a telephone system and I have created a call and a
> party class. *A call can have one to many parties. *For example in a
> conference call there can be 3 or more parties. *In a call transfer
> there can be 3 parties and one of the parties disconnects to transfer
> the call.


ok so far

> I need to be able to traverse the list of parties on each call. *for
> example if each party to the call is disconnected I can remove the
> call object.


what does "remove" mean. Yes , you remove it from the call, but what
happens to it next?

> I create the call object as a pointer and so I delete when the each
> party to the call has disconnected.


why are calls different from parties? They both seem equally dynamic
to me.



>*The call object has a std::list
> of the party objects. *Currently, the list is of party objects, not
> pointers to party objects.


as someone else said, why a list?

> I was wondering if it would be better to change the design so that the
> std::list is of pointers to party. *Or even to have the call object
> create party* 's


that doesn't sound right to me. I'd have thought something external
to the call would create parties.


> and the party object to be a linked list - ie a means
> to SetNextParty(party* next).
>
> But if I implement as a linked list I have the hassle of having to
> delete each party.


I think you have to "delete" or "free" the party however you
implement this. When you transfer a call one party gets removed
and another one added. What happens to the removed party?

>*I would do this when the call* was being deleted.
>
> Anyone got any comments on the best approach?


both parties and calls are dynamic (they appear and disappear
on timescales shorter than the program's) so they need to be handled
in a dynamic fashion. If you don't want new and delete you need
to manage a pool yourself. Somehow.
 
Reply With Quote
 
nick_keighley_nospam@hotmail.com
Guest
Posts: n/a
 
      03-16-2009
On 15 Mar, 18:34, James Kanze <(E-Mail Removed)> wrote:
> On Mar 15, 5:37 pm, Jeff Schwab <(E-Mail Removed)> wrote:
> > Angus wrote:


> > > I create the call object as a pointer and so I delete when
> > > the each party to the call has disconnected.

>
> > Why? *Why not let a standard collection manage the calls, just
> > as a collection manages the parties? *Even if a collection
> > isn't the right tool, a smart-pointer might be.

>
> Because calls (and parties) are entity objects, and have
> explicit lifetimes which have nothing to do with containers (or
> pointers) used for navigation, and you can't use containers of
> the objects, because they don't support copy. *This is a
> classical example of a case where he needs raw pointers; smart
> pointers just lead to more complicated code.


This is refreshing to hear. Maybe my own telecommunication's
background predjudices me...

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Airplane Program with Linked Lists. The linked list portion is veryconfusing to me. jawdoc C++ 9 03-10-2008 03:38 AM
Linked list within a linked list joshd C++ 12 10-02-2006 08:57 AM
Linked list, New try (was:Linked list, no out put,help) fool C Programming 14 07-03-2006 12:29 AM
Generating a char* from a linked list of linked lists Chris Ritchey C++ 7 07-10-2003 10:12 PM
Generating a char* from a linked list of linked lists Chris Ritchey C Programming 7 07-10-2003 10:12 PM



Advertisments