Storing different types in container

L

Larry I Smith

tuvok said:
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
 
A

Artie Gold

Larry said:
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
 
T

tuvok

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)?
 
T

tuvok

Larry I Smith said:
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?
 
L

Larry I Smith

Artie said:
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
 
J

Jason Heyes

Larry I Smith said:
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.
 
B

ben

In addtion, you need all the classes to be polymorphic to be able to cast
from void* to the appropriate type.

ben
 
T

tuvok

Jason Heyes said:
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?
 
J

Jason Heyes

tuvok said:
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.
 
A

Axter

tuvok said:
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.
 
P

Panjandrum

Axter said:
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.
 
B

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
 
J

Jonathan Turkanis

ben said:
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*.

Jonathan
 
L

Larry I Smith

Jason said:
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
 

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,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top