473,886 Members | 2,540 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Templated containers of inherited objects

Hi everyone,

I'd like your help...

Can we have a std::list<BASEw here BASE be the base class of a class
hierarchy? I want to add to this list objects that are inherited from
BASE class but not necessarily the same...

class base {
int x;
};

class child1 : public base {
int d;
};

class child2 : public base {
int e;
};

int main() {
std::list<basem ylist;
child1 _c1;
child2 _c2;
mylist.push_bac k(_c1);
mylist.push_bac k(_c2);
return 0;
}

It seems that I lose the information of _c1 and _c2 like they are
converted to base.

Please, do you have any idea how can I achieve that? Do I have to
implement my own container?

Many thanks in advance,
-- George

Feb 16 '07 #1
21 2231
George Exarchakos wrote:
>

Can we have a std::list<BASEw here BASE be the base class of a class
hierarchy? I want to add to this list objects that are inherited from
BASE class but not necessarily the same...

[redacted]

Please, do you have any idea how can I achieve that? Do I have to
implement my own container?
You've run into the slicing problem. You need to create a container of
(smart) pointers to your base class.

That is, std::list<base* >, or std::list<some_ smart_ptr<base

See the FAQ, http://www.parashift.com/c++-faq-lit....html#faq-34.4


Feb 16 '07 #2
On Feb 16, 5:51 pm, red floyd <no.s...@here.d udewrote:
George Exarchakos wrote:
Can we have a std::list<BASEw here BASE be the base class of a class
hierarchy? I want to add to this list objects that are inherited from
BASE class but not necessarily the same...
[redacted]
>
Please, do you have any idea how can I achieve that? Do I have to
implement my own container?

You've run into the slicing problem. You need to create a container of
(smart) pointers to your base class.

That is, std::list<base* >, or std::list<some_ smart_ptr<base

See the FAQ,http://www.parashift.com/c++-faq-lit....html#faq-34.4
Many thanks Red Floyd! This tip is exactly what I was looking for...
-- George

Feb 16 '07 #3
On 16 Feb 2007 09:17:51 -0800, "George Exarchakos" wrote:
>Can we have a std::list<BASEw here BASE be the base class of a class
hierarchy? I want to add to this list objects that are inherited from
BASE class but not necessarily the same...
STL does not support object-oriented programming. STL containers,
iterators and algorithms are designed only for values, not for
(pointers to) objects. Workarounds exist but with 'Standard' STL there
always remains an 'impedance mismatch' when objects are used.

Best regards,
Roland Pibinger
Feb 16 '07 #4
On Feb 16, 1:05 pm, rpbg...@yahoo.c om (Roland Pibinger) wrote:
On 16 Feb 2007 09:17:51 -0800, "George Exarchakos" wrote:
Can we have a std::list<BASEw here BASE be the base class of a class
hierarchy? I want to add to this list objects that are inherited from
BASE class but not necessarily the same...

STL does not support object-oriented programming.
I think that this comment is misleading. If I understand the point of
the statement, its that using objects that use polymorphism in a
container isn't supported. Because this isn't the case at all.
Although, objects used with the STL must provide certain concepts,
such as default constructibilit y, copy constructibilit y et al.

When dealing with class hierarchies, we must pay special attention to
copy constructibilit y and other concepts because these can lead to
problems such as slicing as noticed by the OP.

Using pointers is a perfectly valid method of fixing this issue.

On the other hand, if Roland meant that "You can't subclass objects
such as std::vector." then he is in fact correct. IIRC, most stl
objects don't provide a virtual destructor. And further, the STL (as
its name suggests) is a library of templates. Using templates with
inheritance is at best tricky.

I'm not sure what the actual standard has to say on this, but g++
4.0.2 won't compile this:

class A
{
public:
A() {}
~A() {}

template< typename TYPE >
virtual void
echo( TYPE val ) = 0 ;
} ;

The error is:
error: invalid use of 'virtual' in template declaration of 'virtual
void A::echo(TYPE)'

This all makes sense if we think in terms of the (non-standard
dictated) vtable implementation of polymorphism. When we create the
vtable for A, we have no idea how many entries it will have.
Theoretically, it would need to have an entry for every template
instantiation of A::echo(TYPE).

Whats more, this class definition could possibly change after it has
been compiled. Ie, compiled in a library, then some client code calls
A::echo(TYPE) with a type thats not used in the library. Thus the
vtable would change and break all sorts of things.

STL containers,
iterators and algorithms are designed only for values, not for
(pointers to) objects.
This is just wrong. A pointer *is* a value. Its a memory address. STL
containers will work just fine with pointers.

Objects on the other hand must provide the required concepts as
mentioned before. The entire point of the STL is to provide a system
that allows for use with any custom type. They'd be pretty pointless
if they could only hold things like int, float, char* et al.

Workarounds exist but with 'Standard' STL there
always remains an 'impedance mismatch' when objects are used.
I'm not entirely certain what 'impedance mismatch' means. Although it
kinda reminds me of studying power amplifiers...

But the point that needs to be made here is that using smart pointers
in a container is not a work around. Smart pointers are a means to
perform resource control. In the case of using pointers, if the only
copy of a pointer to an object is in a std::vector, and then
std::vector::cl ear() is called, then the objects in it are leaked
(assuming we don't have copies to the pointer anywhere else). Smart
pointers do reference counting ( or some other method ) to determine
when an object should be delete'ed. So when std::vector::cl ear() is
called, the smart pointers can determine whether or not the object
should be delete'ed and thuse, no memory is leaked.
Best regards,
Roland Pibinger
HTH,
Paul Davis

Feb 17 '07 #5
On 17 Feb, 01:29, "paul.joseph.da ...@gmail.com"
<paul.joseph.da ...@gmail.comwr ote:
On the other hand, if Roland meant that "You can't subclass objects
such as std::vector." then he is in fact correct. IIRC, most stl
objects don't provide a virtual destructor.
That doesn't stop me deriving from them.
#include <vector>
class foo : public std::vector<int {};

Nothing wrong there. The only thing I can't do without a virtual
destructor is delete polymorphically .

Whether deriving from standard containers is a good idea or not is a
different question, but there is certainly nothing that prevents it.

Gavin Deane

Feb 17 '07 #6
Gavin Deane wrote:
On 17 Feb, 01:29, "paul.joseph.da ...@gmail.com"
<paul.joseph.da ...@gmail.comwr ote:
>On the other hand, if Roland meant that "You can't subclass objects
such as std::vector." then he is in fact correct. IIRC, most stl
objects don't provide a virtual destructor.

That doesn't stop me deriving from them.
#include <vector>
class foo : public std::vector<int {};

Nothing wrong there. The only thing I can't do without a virtual
destructor is delete polymorphically .

Whether deriving from standard containers is a good idea or not is a
different question, but there is certainly nothing that prevents it.
Except that, formally, an implementation of std::vector<tha t prevents
derivation (using a virtual base class trick getting) is standard
compliant. In practice, all implementations of the standard library allow
for derivation; and I do not hesitate to derive from standard container
classes whenever it feels appropriate. However, I do not see any blessing
for this technique in the standard. As far as I can tell, this would be a
compliant implementation:

namespace std {

class __protected_con structor {
protected:

__protected_con structor ( void ) {}

}; // protected_const ructor

template < typename T, typename A >
class vector : private virtual __protected_con structor {

// ... do the vector business.

}; // vector

}
Best

Kai-Uwe Bux
Feb 17 '07 #7
On 16 Feb 2007 17:29:09 -0800, paul joseph wrote:
>On Feb 16, 1:05 pm, rpbg...@yahoo.c om (Roland Pibinger) wrote:
>STL does not support object-oriented programming.

I think that this comment is misleading. If I understand the point of
the statement, its that using objects that use polymorphism in a
container isn't supported.
Just look at the containers, iterators and algorithms. No algorithm
works with (pointers to) objects (except random_shuffle) .
>Because this isn't the case at all.
Although, objects used with the STL must provide certain concepts,
such as default constructibilit y, copy constructibilit y et al.
When dealing with class hierarchies, we must pay special attention to
copy constructibilit y and other concepts because these can lead to
problems such as slicing as noticed by the OP.
Objects (in the meaning used in object-oriented programing) are
characterized by identity, state and behavior. It makes no sense to
copy or assign objects. Copy constructibilit y makes only sense for
values and value-oriented libraries like STL.
>Using pointers is a perfectly valid method of fixing this issue.
If it needs fixing it must be broken.
>STL containers,
>iterators and algorithms are designed only for values, not for
(pointers to) objects.

This is just wrong. A pointer *is* a value. Its a memory address. STL
containers will work just fine with pointers.
A pointer is not a value, otherwise one could just use an int instead.
A pointer in C/C++ has the combined meaning of reference and address.
>Objects on the other hand must provide the required concepts as
mentioned before.
The 'required concepts' make sense only for values, not objects.
>The entire point of the STL is to provide a system
that allows for use with any custom type. They'd be pretty pointless
if they could only hold things like int, float, char* et al.
.... and 'concrete types' as Stroustrup calls them.
>Workarounds exist but with 'Standard' STL there
>always remains an 'impedance mismatch' when objects are used.

I'm not entirely certain what 'impedance mismatch' means. Although it
kinda reminds me of studying power amplifiers...
It means the mismatch that becomes evident when you try to use objects
with the value-based STL library.
>But the point that needs to be made here is that using smart pointers
in a container is not a work around. Smart pointers are a means to
perform resource control.
Since 'smart pointers' only try to imitate real pointers the
'impedance mismatch' is the same.

In general, STL is the attempt introduce the functional paradigm into
the C++ language as counterpart to the object-oriented paradigm. This
attempt has produced much misunderstandin g and confusion.

Best wishes,
Roland Pibinger
Feb 17 '07 #8
* Kai-Uwe Bux:
>
... formally, an implementation of std::vector<tha t prevents
derivation (using a virtual base class trick getting) is standard
compliant.
Sorry, that's incorrect.

§17.3.1.2/1 "The library can be extended by a C++ program. ... Such
extensions are generally one of the following: ... Derived classes."

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 17 '07 #9
On Feb 17, 1:12 pm, rpbg...@yahoo.c om (Roland Pibinger) wrote:
On 16 Feb 2007 17:29:09 -0800, paul joseph wrote:
On Feb 16, 1:05 pm, rpbg...@yahoo.c om (Roland Pibinger) wrote:
STL does not support object-oriented programming.
I think that this comment is misleading. If I understand the point of
the statement, its that using objects that use polymorphism in a
container isn't supported.

Just look at the containers, iterators and algorithms. No algorithm
works with (pointers to) objects (except random_shuffle) .
This examples shows how to use std::sort on a std::vector or pointers.
As well as a trivial example of std::for_each to print the vector.

#include <iostream>
#include <vector>

class A
{
public:
A( int val )
{
_val = val ;
}

~A() {}

int
value()
{
return _val ;
}

private:

int _val ;
} ;

bool
compare( A* lhs, A* rhs )
{
return lhs->value() < rhs->value() ;
}

void
echo( A* a )
{
std::cout << a->value() << std::endl ;
}

int
main( int argc, char* argv[] )
{
std::vector< A* vec ;

for( int i = 10 ; i 0 ; i-- )
{
A* a = new A( i ) ;
vec.push_back( a ) ;
}

std::cout << "Before sort:" << std::endl ;
std::for_each( vec.begin(), vec.end(), echo ) ;

std::sort( vec.begin(), vec.end(), compare ) ;

std::cout << "After sort:" << std::endl ;
std::for_each( vec.begin(), vec.end(), echo ) ;
}
Because this isn't the case at all.
Although, objects used with the STL must provide certain concepts,
such as default constructibilit y, copy constructibilit y et al.
When dealing with class hierarchies, we must pay special attention to
copy constructibilit y and other concepts because these can lead to
problems such as slicing as noticed by the OP.

Objects (in the meaning used in object-oriented programing) are
characterized by identity, state and behavior. It makes no sense to
copy or assign objects. Copy constructibilit y makes only sense for
values and value-oriented libraries like STL.
You're right, wrong, and neither right or wrong. Of course objects are
characterized by their state and behavior. You're absolutely wrong
that it makes no sense to copy or assign objects, there are instances
where this may be true, but its just plain wrong to say never. I use
it quite a bit.

And the last bit that copy constructibilit y only makes sense in the
STL isn't quite right, although I don't tend to use it alot in my own
code, thats mostly becuase I don't write code that requires this
concept.
Using pointers is a perfectly valid method of fixing this issue.

If it needs fixing it must be broken.
STL containers,
iterators and algorithms are designed only for values, not for
(pointers to) objects.
This is just wrong. A pointer *is* a value. Its a memory address. STL
containers will work just fine with pointers.

A pointer is not a value, otherwise one could just use an int instead.
A pointer in C/C++ has the combined meaning of reference and address.
You can use an int for a pointer! (Disclaimer: Its very ill advised,
bad C++, and requires that an int be the same size as the pointer you
wish to obfuscate.)
Objects on the other hand must provide the required concepts as
mentioned before.

The 'required concepts' make sense only for values, not objects.
The entire point of the STL is to provide a system
that allows for use with any custom type. They'd be pretty pointless
if they could only hold things like int, float, char* et al.

... and 'concrete types' as Stroustrup calls them.
Workarounds exist but with 'Standard' STL there
always remains an 'impedance mismatch' when objects are used.
I'm not entirely certain what 'impedance mismatch' means. Although it
kinda reminds me of studying power amplifiers...

It means the mismatch that becomes evident when you try to use objects
with the value-based STL library.
But the point that needs to be made here is that using smart pointers
in a container is not a work around. Smart pointers are a means to
perform resource control.

Since 'smart pointers' only try to imitate real pointers the
'impedance mismatch' is the same.
I'm unsure as to how I should respond to this.

Yes, smart pointers only imitate real pointers. They are actually
objects that use a little voodoo to track the resources they own (The
underlying raw pointer). Because they are objects, they can be copied
and assigned. Writing code without smart pointers is ill-advised in my
opinion.

The only 'mismatch' that occurs with the objects used in the STL is
when the object doesn't support something required of it. The
algorithms in the STL were designed to work with any user defined type
as long as those types support a few basic operations. Obviously, if
something doesn't meet these requirements it won't work. You'll find
this happens alot when requirements aren't met.
In general, STL is the attempt introduce the functional paradigm into
the C++ language as counterpart to the object-oriented paradigm. This
attempt has produced much misunderstandin g and confusion.
Obviously the STL can be misunderstood.. .
Best wishes,
Roland Pibinger

Feb 17 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
2327
by: Jon Wilson | last post by:
I have a class which needs to accumulate data. The way we get this data is by calling a member function which returns float on a number of different objects of different type (they are all the same type for a given instance of the class, but different types for different instances.) #include<set> using namespace std; template<class T>
4
1872
by: Lionel B | last post by:
Greetings, The following code: <code> template<typename T> class A { protected:
18
3070
by: Matthias Kaeppler | last post by:
Hi, in my program, I have to sort containers of objects which can be 2000 items big in some cases. Since STL containers are based around copying and since I need to sort these containers quite frequently, I thought it'd be a better idea to manage additional containers which are initialized with pointers to the objects in the primary containers and sort those (only pointers have to be copied around then). However, that also means if I...
6
1319
by: Alex | last post by:
I have been loving the templated datacolumns of the datagrid. I have stumbled onto a problem though that is beyond by knowledge and I was hoping someone here could jumpstart me. My templated columns work find as long as I pass in a dataset but if I pass in a collection of objects then they won't work unless I can cast the correct object and then fill in the column with the object. My current code looks like this: public void...
13
2242
by: algorimancer | last post by:
I use the STL collection classes a lot, and frequently find myself writing something like: vector<CDataClass>::iterator iter=DataClassCollection.begin(); vector<CDataClass>::iterator iter_end=DataClassCollection.end(); for(;iter!=iter_end;++iter) { //doing stuff with iter... }
2
1813
by: Pete C | last post by:
Hello... I am writing a templated 'wrapper' class that takes as its template parameter a class to be inherited from. I need a specialisation of this wrapper class in certain cases, however I am having trouble with the specialisation when its parameter is itself a templated class. The following code compiles with g++ 4.0.3, however Comeau says it's invalid. Is what I'm trying to do possible in C++, or is there another way to do the...
1
1500
by: cpunerd | last post by:
Hello, I'm not new to C++, but for some reason, until now I'd never had a need for deriving templated classes. Now though, I find myself seeing a weird problem. If I have a templated base class (Base), and a template derived class (Derived, which is publicly inherited from Base with the same template parameters), why must I prefix all "Base" member accesses in "Derived" with Base<template arguments>? Is there perhaps another method that...
2
2945
by: domehead100 | last post by:
I have a templated class, CDerived: template <typename TValue, typename TDraw, typename TEdit ...> class CDerived : public CBase { TValue m_Value public: TValue& GetValue() const {
2
2295
card
by: card | last post by:
Hi everyone, I have a question about referencing a nested class contained within a templated class. Of course the best way to show you is by example. Here's my templated classes: #include <stack> template <class T> class A { public:
0
9956
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9799
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11172
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10770
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10872
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9592
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7987
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5808
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4627
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.