By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,797 Members | 1,794 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,797 IT Pros & Developers. It's quick & easy.

canonical up-cast idiom for smart pointers?

P: n/a
I'm wondering if there is a way to do this properly. I feel like I am
missing something.

I have two distinct classes. They don't have much at all in common.
I want a vector-like container that contains smart pointers
(boost::shared_ptr or similar) to a set of these two classes and keeps
them sorted wrt each other.

For example if I insert ClassA, ClassA, ClassB, ClassA, ClassB in that
order, I want to re-visit them in that same order when I iterate
later.

My first thought was to make an artificial base class that has a
'type' argument indicating which "derived" type was stored. Then a
simple vector< shared_ptr<Base gets me my objects back. The
problem, of course, is that I get back pointers to the Base type.

Is there an idiomatic way to go from shared_ptr<Baseto
shared_ptr<Derived? I note that the compiler happily goes the other
way automatically.

Or maybe there is another idiomatic way to store this data? I can
think of a half-dozen ways (seperate vectors with a third switcher
vector, etc), but they all seem dirty.

Is there a better way?

Tim

Mar 17 '07 #1
Share this Question
Share on Google+
3 Replies


P: n/a
On Mar 17, 11:19 am, "Tim H" <thoc...@gmail.comwrote:
I have two distinct classes. They don't have much at all
in common.
I want a vector-like container that contains smart
pointers (boost::shared_ptr or similar) to a set of these
two classes and keeps them sorted wrt each other.
You're contradicting yourself. If those two classes don't
have much in common, why are you trying to store them in
the same vector? Presumably, because you want to iterate
over the vector, retrieve the objects and do-something with
them depending on what they are. The point is,
do-something-after-being-retrieved-from-a-vector is exactly
what they have in common then, even if the implementations
vastly differ between the classes.

And that's exactly the thing that belongs to an abstract
base class that both your classes should inherit from.
For example if I insert ClassA, ClassA, ClassB, ClassA,
ClassB in that order, I want to re-visit them in that
same order when I iterate later.
And do-something, right? So instead of (pseudocode):

if ( ( * base_object ) is-a ClassA object )
base_object -do_some_ClassA_stuff ( ) ;
else
base_object -do_some_ClassB_stuff ( ) ;

....make that:

baseObject -do_stuff ( ) ;

And let the objects themselves worry about what exactly
should be done.
My first thought was to make an artificial base class
that has a 'type' argument indicating which "derived"
type was stored.
And why would you want to know? Let the objects handle the
differences. Why implement the polymorphism by hand if you
can have the compiler handle the grisly details for you?
Is there an idiomatic way to go from shared_ptr<Baseto
shared_ptr<Derived?
Why would you want to? If the objects are so vastly
different you can't do with a pointer to a base class, they
shouldn't be stored together. If they have something in
common that allows them to be processed together, that
something-in-common belongs to the base class, in which
case the base class pointer should suffice (and
implementations will handle the differences).

All in all, it looks like more of a design problem than a
C++ problem to me. Perhaps you should consult the gurus in
comp.object.

--
roy axenov

Mar 17 '07 #2

P: n/a
Tim H wrote:

[snip]
Is there an idiomatic way to go from shared_ptr<Baseto
shared_ptr<Derived?
There are tr1::dynamic_pointer_cast<and tr1::static_pointer_cast<>.

Note that the need for up-casting may indicate a design problem.
Best

Kai-Uwe Bux
Mar 17 '07 #3

P: n/a
On Mar 17, 3:22 am, "roy axenov" <r_axe...@mail.ruwrote:
You're contradicting yourself. If those two classes don't
have much in common, why are you trying to store them in
the same vector?
It's a filesystem-like structure. Think directories and files. There
are a whole host of things you do with files that don't apply to
directories, and there are a whole host of things you do with
directories that you don't do to files. And yet, when you run 'ls'
you see them intermixed.

This is not a perfect analogy for the problem at hand, but it's
close. These two (for now, could be more) classes are distinct, but I
want to store them in the order they were discovered wrt each other.
Is there an idiomatic way to go from shared_ptr<Baseto
shared_ptr<Derived?

Why would you want to?
I don't want to, but that's why I am here. This feels like wrong
design, and I am looking for a better answer. That said, it should be
*possible* because I know through my own meta-data that it's safe, and
in the end it's just a pointer.
All in all, it looks like more of a design problem than a
C++ problem to me. Perhaps you should consult the gurus in
comp.object.
Might just do that. Thanks.

Tim

Mar 17 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.