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

Storing different types in container

P: n/a
How can objects of different types be stored in a collection?
For example:

struct S1 { /*...*/ };
struct S2 { /*...*/ };
struct Sn { /*...*/ };

template<typename T> class X
{
public:
T data;
X() {}
//...
};

//...
X<S1> x1;
X<S2> x2;
X<Sn> xn;

Can these objects be stored in the same collection class (for example in a vector or map)?

Jul 23 '05 #1
Share this Question
Share on Google+
17 Replies


P: n/a
ben

Can these objects be stored in the same collection class (for example in a

vector or map)?

No unless you try to use dangerous vector<void*>.

ben
Jul 23 '05 #2

P: n/a
ben wrote:
Can these objects be stored in the same collection class (for
example in a vector or map)?
No unless you try to use dangerous vector<void*>.


Or the alluring vector<boost::any> ;-)
ben


Jonathan
Jul 23 '05 #3

P: n/a
tuvok wrote:
How can objects of different types be stored in a collection?
For example:

struct S1 { /*...*/ };
struct S2 { /*...*/ };
struct Sn { /*...*/ };

template<typename T> class X
{
public:
T data;
X() {}
//...
};

//...
X<S1> x1;
X<S2> x2;
X<Sn> xn;

Can these objects be stored in the same collection class (for example in a vector or map)?


IF they all derive from the same base class (e.g. circle, rectangle,
triangle all derive from shape), then you can store them as
objects of the base class (e.g. as 'shape'). Otherwise - no.

Regards,
Larry
Jul 23 '05 #4

P: n/a
"Larry I Smith" <la***********@verizon.net> wrote
tuvok wrote:
How can objects of different types be stored in a collection?
For example:

struct S1 { /*...*/ };
struct S2 { /*...*/ };
struct Sn { /*...*/ };

template<typename T> class X
{
public:
T data;
X() {}
//...
};

//...
X<S1> x1;
X<S2> x2;
X<Sn> xn;

Can these objects be stored in the same collection class (for example in a vector or map)?


IF they all derive from the same base class (e.g. circle, rectangle,
triangle all derive from shape), then you can store them as
objects of the base class (e.g. as 'shape'). Otherwise - no.


Something like the following?

template<typename T> class X : public B { /* see above */ }

How would this be added to a std::vector?
Jul 23 '05 #5

P: n/a
Larry I Smith wrote:
tuvok wrote:
How can objects of different types be stored in a collection?
For example:

struct S1 { /*...*/ };
struct S2 { /*...*/ };
struct Sn { /*...*/ };

template<typename T> class X
{
public:
T data;
X() {}
//...
};

//...
X<S1> x1;
X<S2> x2;
X<Sn> xn;

Can these objects be stored in the same collection class (for example in a vector or map)?

IF they all derive from the same base class (e.g. circle, rectangle,
triangle all derive from shape), then you can store them as
objects of the base class (e.g. as 'shape'). Otherwise - no.

Erm...

You can store *pointers* to them (but not the objects themselves) as
*pointers to the base class* in this case; of course in that case, you'd
have to manage the objects' lifetimes manually.

HTH,
--ag
--
Artie Gold -- Austin, Texas
http://it-matters.blogspot.com (new post 12/5)
http://www.cafepress.com/goldsays
Jul 23 '05 #6

P: n/a
Artie Gold wrote:
Larry I Smith wrote:
tuvok wrote:
How can objects of different types be stored in a collection?
For example:

struct S1 { /*...*/ };
struct S2 { /*...*/ };
struct Sn { /*...*/ };

template<typename T> class X
{
public:
T data;
X() {}
//...
};

//...
X<S1> x1;
X<S2> x2;
X<Sn> xn;

Can these objects be stored in the same collection class (for example
in a vector or map)?

IF they all derive from the same base class (e.g. circle, rectangle,
triangle all derive from shape), then you can store them as
objects of the base class (e.g. as 'shape'). Otherwise - no.

Erm...

You can store *pointers* to them (but not the objects themselves) as
*pointers to the base class* in this case; of course in that case, you'd
have to manage the objects' lifetimes manually.

HTH,
--ag


Yes, you are correct. Base class pointers only...

Larry
Jul 23 '05 #7

P: n/a
"Larry I Smith" <la***********@verizon.net> wrote in message
news:WHPqe.418$1q5.323@trnddc02...
Artie Gold wrote:
Larry I Smith wrote:
tuvok wrote:

How can objects of different types be stored in a collection?
For example:

struct S1 { /*...*/ };
struct S2 { /*...*/ };
struct Sn { /*...*/ };

template<typename T> class X
{
public:
T data;
X() {}
//...
};

//...
X<S1> x1;
X<S2> x2;
X<Sn> xn;

Can these objects be stored in the same collection class (for example
in a vector or map)?

IF they all derive from the same base class (e.g. circle, rectangle,
triangle all derive from shape), then you can store them as
objects of the base class (e.g. as 'shape'). Otherwise - no.

Erm...

You can store *pointers* to them (but not the objects themselves) as
*pointers to the base class* in this case; of course in that case, you'd
have to manage the objects' lifetimes manually.

HTH,
--ag


Yes, you are correct. Base class pointers only...


Write a class to encapsulate the base class and hide the management of
object lifetime using boost::shared_ptr. Objects (not pointers to objects)
of the base-encapsulating class can be stored in a std::vector like any
other object.
Jul 23 '05 #8

P: n/a
"Jason Heyes" <ja********@optusnet.com.au> wrote
"Larry I Smith" <la***********@verizon.net> wrote in message
Artie Gold wrote:
Larry I Smith wrote:
tuvok wrote:

> Can these objects be stored in the same collection class (for example
> in a vector or map)?
>
IF they all derive from the same base class (e.g. circle, rectangle,
triangle all derive from shape), then you can store them as
objects of the base class (e.g. as 'shape'). Otherwise - no.

Erm...

You can store *pointers* to them (but not the objects themselves) as
*pointers to the base class* in this case; of course in that case, you'd
have to manage the objects' lifetimes manually.

HTH,
--ag


Yes, you are correct. Base class pointers only...


Write a class to encapsulate the base class and hide the management of
object lifetime using boost::shared_ptr. Objects (not pointers to objects)
of the base-encapsulating class can be stored in a std::vector like any
other object.


Will then the right virtual functions be invoked?
Jul 23 '05 #9

P: n/a
ben
In addtion, you need all the classes to be polymorphic to be able to cast
from void* to the appropriate type.

ben

No unless you try to use dangerous vector<void*>.

ben

Jul 23 '05 #10

P: n/a
"tuvok" <52***************@t-online.de> wrote in message
news:d8*************@news.t-online.com...
"Jason Heyes" <ja********@optusnet.com.au> wrote
"Larry I Smith" <la***********@verizon.net> wrote in message
> Artie Gold wrote:
>> Larry I Smith wrote:
>>> tuvok wrote:
>>>
>>>> Can these objects be stored in the same collection class (for
>>>> example
>>>> in a vector or map)?
>>>>
>>> IF they all derive from the same base class (e.g. circle, rectangle,
>>> triangle all derive from shape), then you can store them as
>>> objects of the base class (e.g. as 'shape'). Otherwise - no.
>>>
>> Erm...
>>
>> You can store *pointers* to them (but not the objects themselves) as
>> *pointers to the base class* in this case; of course in that case,
>> you'd
>> have to manage the objects' lifetimes manually.
>>
>> HTH,
>> --ag
>
> Yes, you are correct. Base class pointers only...
>


Write a class to encapsulate the base class and hide the management of
object lifetime using boost::shared_ptr. Objects (not pointers to
objects)
of the base-encapsulating class can be stored in a std::vector like any
other object.


Will then the right virtual functions be invoked?


Absolutely. For example, say Animal is your base and Animal has a virtual
function called make_noise. Here is the encapsulating class (called a
handle) for the Animal base class:

class AnimalHandle
{
boost::shared_ptr<Animal> animal_ptr;

public:
AnimalHandle() : animal_ptr(new Animal()) { }

void make_noise() const { animal_ptr->make_noise(); }
};

You can store AnimalHandle objects in std::vector. You don't need to store
pointers to AnimalHandle.
Jul 23 '05 #11

P: n/a
tuvok wrote:
How can objects of different types be stored in a collection?
For example:

struct S1 { /*...*/ };
struct S2 { /*...*/ };
struct Sn { /*...*/ };

template<typename T> class X
{
public:
T data;
X() {}
//...
};

//...
X<S1> x1;
X<S2> x2;
X<Sn> xn;

Can these objects be stored in the same collection class (for example in a vector or map)?


You can create a Heterogeneous Container if all the types have a
commone method or data type.
A Heterogeneous Container is a container of different types that have
NO common base type.

This method requires a wrapper class, that gives access to the common
method and/or data.

See following links for example code:
http://code.axter.com/HeterogeneousContainer1.cpp
http://code.axter.com/HeterogeneousContainer2.cpp
http://code.axter.com/HeterogeneousContainer3.cpp

Some compilers may have problems with the last example.

Jul 23 '05 #12

P: n/a
Axter wrote:
You can create a Heterogeneous Container if all the types have a
commone method or data type.
A Heterogeneous Container is a container of different types that have
NO common base type.

This method requires a wrapper class, that gives access to the common
method and/or data.

See following links for example code:
http://code.axter.com/HeterogeneousContainer1.cpp
http://code.axter.com/HeterogeneousContainer2.cpp
http://code.axter.com/HeterogeneousContainer3.cpp

Some compilers may have problems with the last example.


Some humans may have problems with contrived designs.

Jul 23 '05 #13

P: n/a
ben
> Some humans may have problems with contrived designs.


It's still inheritance, only that the template generates function code every
time you AddToPocket(), which bridges the heterogeneous objects to a common
base.

ben
Jul 23 '05 #14

P: n/a
tuvok wrote:
How can objects of different types be stored in a collection?


http://www.boost.org/doc/html/any.html
Jul 23 '05 #15

P: n/a
Phil Endecott wrote:
http://www.boost.org/doc/html/any.html


Repost

Jul 23 '05 #16

P: n/a
ben wrote:
In addtion, you need all the classes to be polymorphic to be able to
cast from void* to the appropriate type.
All that's needed is a way to remember the original type. This can be done
several ways.

You can't dynamic_cast from a void*.
ben


Jonathan
Jul 23 '05 #17

P: n/a
Jason Heyes wrote:
"tuvok" <52***************@t-online.de> wrote in message
news:d8*************@news.t-online.com...
"Jason Heyes" <ja********@optusnet.com.au> wrote
"Larry I Smith" <la***********@verizon.net> wrote in message
Artie Gold wrote:
>Larry I Smith wrote:
>>tuvok wrote:
>>
>>>Can these objects be stored in the same collection class (for
>>>example
>>>in a vector or map)?
>>>
>>IF they all derive from the same base class (e.g. circle, rectangle,
>>triangle all derive from shape), then you can store them as
>>objects of the base class (e.g. as 'shape'). Otherwise - no.
>>
>Erm...
>
>You can store *pointers* to them (but not the objects themselves) as
>*pointers to the base class* in this case; of course in that case,
>you'd
>have to manage the objects' lifetimes manually.
>
>HTH,
>--ag
Yes, you are correct. Base class pointers only...

Write a class to encapsulate the base class and hide the management of
object lifetime using boost::shared_ptr. Objects (not pointers to
objects)
of the base-encapsulating class can be stored in a std::vector like any
other object.

Will then the right virtual functions be invoked?


Absolutely. For example, say Animal is your base and Animal has a virtual
function called make_noise. Here is the encapsulating class (called a
handle) for the Animal base class:

class AnimalHandle
{
boost::shared_ptr<Animal> animal_ptr;

public:
AnimalHandle() : animal_ptr(new Animal()) { }

void make_noise() const { animal_ptr->make_noise(); }
};

You can store AnimalHandle objects in std::vector. You don't need to store
pointers to AnimalHandle.


You should advise the OP that Boost is not part of the C++ Standard.
It's an add-on that will have to be obtained/installed.

http://www.boost.org/

Larry
Jul 23 '05 #18

This discussion thread is closed

Replies have been disabled for this discussion.