Please help me to choose a proper container

J

Jayden Shui

Hi All,

I have a number of named objects of type B whose name can be accessed
by B::Name(). B is polymorphic. D1, D2 and so on are derived from B. I
want to put them in a set or map-like container ordered by their
names. They can be used by other objects, such as of type C. If the
objects in the container are changed by its type (from type D1 to D2)
or value, their users can know it automatically, i.e. those
information is shared among owners and users. To erase an object in
the container, first we need to ensure it is not used by other
objects.

Please give me your idea on it by choosing a proper container with
smart pointers. I am struggling with it and cannot find a good way.

Thanks a lot ! !

Best regards,

Jayden
 
V

Victor Bazarov

I have a number of named objects of type B whose name can be accessed
by B::Name(). B is polymorphic. D1, D2 and so on are derived from B. I
want to put them in a set or map-like container ordered by their
names. They can be used by other objects, such as of type C. If the
objects in the container are changed by its type (from type D1 to D2)

Huh? Type is a lifelong attribute of any object. Objects do NOT change
their types. What you could have is an object of type D1 goes away and
another object (of type D2) is put it the former object's place.
or value, their users can know it automatically, i.e. those
information is shared among owners and users. To erase an object in
the container, first we need to ensure it is not used by other
objects.

Please give me your idea on it by choosing a proper container with
smart pointers. I am struggling with it and cannot find a good way.

Containers aren't chosen by the behavior of their contained elements.
They are usually chosen by the speed/complexity of access, memory
requirements for storage, const-ness of objects, etc. Associative
containers can either be automatically sorted (you can have a set of
objects sorted by means of any custom comparator), etc. What you need
is probably a multiset.

V
 
R

Richard

[Please do not mail me a copy of your followup]

Victor Bazarov <[email protected]> spake the secret code
Containers aren't chosen by the behavior of their contained elements.

Sometimes, but not always. For example, vector imposes the requirement
that elements be copyable, but list does not.
 
C

Christopher

Hi All,

I have a number of named objects of type B whose name can be accessed
by B::Name(). B is polymorphic. D1, D2 and so on are derived from B. I
want to put them in a set or map-like container ordered by their
names. They can be used by other objects, such as of type C. If the
objects in the container are changed by its type (from type D1 to D2)
or value, their users can know it automatically, i.e. those
information is shared among owners and users. To erase an object in
the container, first we need to ensure it is not used by other
objects.

Please give me your idea on it by choosing a proper container with
smart pointers. I am struggling with it and cannot find a good way.

Everything you've said here has little to do with what type of
container to choose.

If you intend on using smart pointers, then I know that at least the
boost::shared_ptr variety meet all the requirements to be used with
and of the STL containers. So, why not just put them in a map?

You need to decide whether or not the name is a good key.
Is it unique for each object?
Is comparison quick?

Is it required that your class have name data and a method to get it
or set it for purposes aside from providing a key to the map?
If not, then just use name as the key to the map and take it out of
your class so as to not duplicate. If so, then leave it.
 
W

Waldek M.

If you intend on using smart pointers, then I know that at least the
boost::shared_ptr variety meet all the requirements to be used with
and of the STL containers. So, why not just put them in a map?

Or better yet, std::tr1::shared_ptr, to avoid external
library (unless the OP has that already).
Also the std::tr1::weak_ptr might be required, depending on what the OP
really needs to do with the object (when are they destroyed).

Best regards,
Waldek
 
J

Juha Nieminen

Christopher said:
Is it required that your class have name data and a method to get it
or set it for purposes aside from providing a key to the map?
If not, then just use name as the key to the map and take it out of
your class so as to not duplicate. If so, then leave it.

You did not explain how it should be done if the name is an integral
(and immutable) part of the objects, and hence a std::set would be better.

In that case you need to provide a comparator to std::set, for example
like this:

typedef std::shared_ptr<MyClass> MyClassPtr;

struct MyClassPtrComparator
{
bool operator()(const MyClassPtr& ptr1, const MyClassPtr& ptr2) const
{
return ptr1->name() < ptr2->name();
}
};

typedef std::set<MyClassPtr, MyClassPtrComparator> MyClassPtrSet;

....

MyClassPtrSet theSet;
theSet.insert(new MyDerivedClass);
 

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

Members online

No members online now.

Forum statistics

Threads
473,965
Messages
2,570,148
Members
46,710
Latest member
FredricRen

Latest Threads

Top