Deriving a regular class from a template? | |
This may be another question having an obvious answer, but I'm not seeing
it. I'm trying to create a class that derives from
std::valarray<std::string>. I don't need a template, and I haven't come
across any examples of a construct like what I show below. Perhapes it's
simply a bad idea. If there is something fundamentally wrong with this
approach please let me know.
Can anybody tell me if there is a way to get the following to work? I can
get the class StringArray to compile, but it fails to link correctly:
#include <valarray>
#include <string>
namespace stringer{
using std::valarray;
using std::string;
class StringArray:public valarray<string> {
public:
StringArray(const size_t& vsize):valarray<string>(vsize){}
};
StringArray stringV(3); // this is what seems to be failing
}
This is the point where it fails:
g++ -o stringer main.o -L/usr/lib/ -L/usr/lib/qt3/lib/ -L/usr/X11R6/lib/
-lqt -lXext -lX11 -lm
main.o(.text+0xd7): In function `__static_initialization_and_destruction_
(int, int)':
: undefined reference to `std::basic_string<char, std::char_traits<char>,
std::allocator<char> >::_Rep::_S_empty_rep_storage'
main.o(.text+0x155): In function `__static_initialization_and_destruction_
(int, int)':
: undefined reference to `std::basic_string<char, std::char_traits<char>,
std::allocator<char> >::_Rep::_S_empty_rep_storage'
main.o(.text+0x196): In function `__static_initialization_and_destruction_
(int, int)':
: undefined reference to `__gnu_cxx::__exchange_and_add(int volatile*, int)'
--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org | | | | re: Deriving a regular class from a template?
"Steven T. Hatton" <susudata@setidava.kushan.aa> wrote in message
news:u5adnYHwA7ipGBXdRVn-jw@speakeasy.net...[color=blue]
> This may be another question having an obvious answer, but I'm not seeing
> it. I'm trying to create a class that derives from
> std::valarray<std::string>. I don't need a template, and I haven't come
> across any examples of a construct like what I show below. Perhapes it's
> simply a bad idea. If there is something fundamentally wrong with this
> approach please let me know.
>
> Can anybody tell me if there is a way to get the following to work? I can
> get the class StringArray to compile, but it fails to link correctly:
>
> #include <valarray>
> #include <string>
>
> namespace stringer{
> using std::valarray;
> using std::string;
>
> class StringArray:public valarray<string> {
> public:
> StringArray(const size_t& vsize):valarray<string>(vsize){}
> };
>
> StringArray stringV(3); // this is what seems to be failing
> }
>
> This is the point where it fails:
>
> g++ -o stringer[/color]
main.o -L/usr/lib/ -L/usr/lib/qt3/lib/ -L/usr/X11R6/lib/[color=blue]
> -lqt -lXext -lX11 -lm
> main.o(.text+0xd7): In function `__static_initialization_and_destruction_
> (int, int)':
> : undefined reference to `std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >::_Rep::_S_empty_rep_storage'
> main.o(.text+0x155): In function `__static_initialization_and_destruction_
> (int, int)':
> : undefined reference to `std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >::_Rep::_S_empty_rep_storage'
> main.o(.text+0x196): In function `__static_initialization_and_destruction_
> (int, int)':
> : undefined reference to `__gnu_cxx::__exchange_and_add(int volatile*,[/color]
int)'[color=blue]
>[/color]
Your code compiles and links for me. I can't see anything illegal about it.
OTOH I'm not sure its a good idea.
Firstly from the code you posted
typedef std::valarray<std::string> StringArray;
seems a simpler option, but maybe you have reasons for doing this that
aren't in the posted code.
Secondly valarray is really designed for numeric types, I don't think using
it with strings is illegal but its a bit odd, why not
std::vector<std::string>?
Thirdly deriving from standard container classes is frowned upon because
they lack a virtual destructor. Something like this is safer and may be
closer to your needs
class StringArray
{
public:
...
private:
std::valarray<std::string> data;
};
john | | | | re: Deriving a regular class from a template?
John Harrison wrote:
[color=blue]
> Your code compiles and links for me. I can't see anything illegal about
> it.[/color]
Indeed. I just built and installed gcc (GCC) 3.4.0. I had been using qmake
to create the Makefile. That's would have worked if my setup were
standard. But it was trying to link against a different set of libs. In
particular the -L/usr/lib. I thought gcc would take precedence over that,
until I looked it up. Oh, and then there's the aclocal-1.8 that came with
automake, and didn't get the proper symlink from the `make install'! It
goes on and on... :-/
[color=blue]
> OTOH I'm not sure its a good idea.
>
> Firstly from the code you posted
>
> typedef std::valarray<std::string> StringArray;
>
> seems a simpler option, but maybe you have reasons for doing this that
> aren't in the posted code.[/color]
My initial motivation was to set the values of the valarray in an
initialization function, hence the desire for a derived class.
[color=blue]
> Secondly valarray is really designed for numeric types, I don't think
> using it with strings is illegal but its a bit odd, why not
> std::vector<std::string>?[/color]
I'm using the strings so I can mark the individual elements while I play
around with different slicing, indexing and etc. It's just a learning toy.
[color=blue]
> Thirdly deriving from standard container classes is frowned upon because
> they lack a virtual destructor.[/color]
That's good to know. I'm now wondering if I can explicitly call the
destructor on the baseclass. Hmmmm....
[color=blue]
> Something like this is safer and may be
> closer to your needs
>
> class StringArray
> {
> public:
> ...
> private:
> std::valarray<std::string> data;
> };[/color]
That crossed my mind. In this case, it's probably better to do the has-a
rather than an is-a. Thanks for the help. The verification that it
compiled was valuable information.
--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org | | | | re: Deriving a regular class from a template?
"Steven T. Hatton" <susudata@setidava.kushan.aa> wrote in message news:<u5adnYHwA7ipGBXdRVn-jw@speakeasy.net>...[color=blue]
> This may be another question having an obvious answer, but I'm not seeing
> it. I'm trying to create a class that derives from
> std::valarray<std::string>. I don't need a template, and I haven't come
> across any examples of a construct like what I show below. Perhapes it's
> simply a bad idea. If there is something fundamentally wrong with this
> approach please let me know.
>
> Can anybody tell me if there is a way to get the following to work? I can
> get the class StringArray to compile, but it fails to link correctly:
>
> #include <valarray>
> #include <string>
>
> namespace stringer{
> using std::valarray;
> using std::string;
>
> class StringArray:public valarray<string> {
> public:
> StringArray(const size_t& vsize):valarray<string>(vsize){}
> };
>
> StringArray stringV(3); // this is what seems to be failing
> }
>
> This is the point where it fails:
>
> g++ -o stringer main.o -L/usr/lib/ -L/usr/lib/qt3/lib/ -L/usr/X11R6/lib/
> -lqt -lXext -lX11 -lm
> main.o(.text+0xd7): In function `__static_initialization_and_destruction_
> (int, int)':
> : undefined reference to `std::basic_string<char, std::char_traits<char>,[/color]
[color=blue]
> : undefined reference to `__gnu_cxx::__exchange_and_add(int volatile*, int> std::allocator<char> >::_Rep::_S_empty_rep_storage'
> main.o(.text+0x155): In function `__static_initialization_and_destruction_
> (int, int)':
> : undefined reference to `std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >::_Rep::_S_empty_rep_storage'
> main.o(.text+0x196): In function `__static_initialization_and_destruction_
> (int, int)':)'[/color]
One possibility is that, since the std::valarray container is really
for optimized numerical calculations, it has some special restrictions
which cause problems if you try to initialize a valarray with a
non-numerical type (c.f. sec 26.3 of the standard). I would suggest
using std::vector<std::string> .. that should definitely work .. I
have used it myself in the past.
HTH, Dave Moore | | | | re: Deriving a regular class from a template?
"Steven T. Hatton" <susudata@setidava.kushan.aa> wrote in message news:<u5adnYHwA7ipGBXdRVn-jw@speakeasy.net>...
[color=blue]
> Can anybody tell me if there is a way to get the following to work? I can
> get the class StringArray to compile, but it fails to link correctly:
>
> #include <valarray>
> #include <string>
>
> namespace stringer{
> using std::valarray;
> using std::string;
>
> class StringArray:public valarray<string> {
> public:
> StringArray(const size_t& vsize):valarray<string>(vsize){}
> };
>
> StringArray stringV(3); // this is what seems to be failing
> }[/color]
Should work, and in fact works when compiled with VC7.1. It seems
you should ask in the group for your compiler.
Regards,
Michiel Salters | | | | re: Deriving a regular class from a template?
"Steven T. Hatton" <susudata@setidava.kushan.aa> wrote in message news:<u5adnYHwA7ipGBXdRVn-jw@speakeasy.net>...[color=blue]
> This may be another question having an obvious answer, but I'm not seeing
> it. I'm trying to create a class that derives from
> std::valarray<std::string>.[/color]
This is a bad idea, for at least three reasons:
i) valarray is a special container designed for numerical applications,
so there is propbably no point in using it with string
ii) IIRC there are some restrictions in the standard for using valarray,
to the consequence that using it with string yields undefined
behaviour
iii) deriving from classes which are not designed as base classes, like
the standard library containers, is considered bad practice in C++,
e.g. the lack of a virtual destructor may prove fatal
To your more general question if one can derive a concrete class from
a template instantiation: Yes, that's possible.
If you had used vector instead of valarray, your example would be correct,
even if bad style, for reason iii).
And if you look at your error message, you might see that the code as written
compiled fine. The error message refers to a linker error. You are probable
not linking against the C++ runtime library, or maybe you are linking against
a wrong one.
To solve this problem, check your documentation or ask in a newsgroup topical
to your compiler system.
[color=blue]
> I don't need a template, and I haven't come
> across any examples of a construct like what I show below. Perhapes it's
> simply a bad idea. If there is something fundamentally wrong with this
> approach please let me know.
>
> Can anybody tell me if there is a way to get the following to work? I can
> get the class StringArray to compile, but it fails to link correctly:
>
> #include <valarray>
> #include <string>
>
> namespace stringer{
> using std::valarray;
> using std::string;
>
> class StringArray:public valarray<string> {
> public:
> StringArray(const size_t& vsize):valarray<string>(vsize){}
> };
>
> StringArray stringV(3); // this is what seems to be failing
> }
>
> This is the point where it fails:
>
> g++ -o stringer main.o -L/usr/lib/ -L/usr/lib/qt3/lib/ -L/usr/X11R6/lib/
> -lqt -lXext -lX11 -lm
> main.o(.text+0xd7): In function `__static_initialization_and_destruction_
> (int, int)':
> : undefined reference to `std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >::_Rep::_S_empty_rep_storage'
> main.o(.text+0x155): In function `__static_initialization_and_destruction_
> (int, int)':
> : undefined reference to `std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >::_Rep::_S_empty_rep_storage'
> main.o(.text+0x196): In function `__static_initialization_and_destruction_
> (int, int)':
> : undefined reference to `__gnu_cxx::__exchange_and_add(int volatile*, int)'[/color] | | | | re: Deriving a regular class from a template?
>[color=blue][color=green]
> > Thirdly deriving from standard container classes is frowned upon because
> > they lack a virtual destructor.[/color]
>
> That's good to know. I'm now wondering if I can explicitly call the
> destructor on the baseclass. Hmmmm....
>[/color]
There's no need to do that. The problem is with code like the following
valarray<string>* p = new StringArray(10);
delete p;
That is undefined behaviour. Deleting a derived class object through a
pointer to a base class when that base class lacks a virtual destructor
results in undefined behaviour. The issue for you is how likely it is that
code like the above will be written with your StringArray class.
john | | | | re: Deriving a regular class from a template? schnitkerAffenschaukel@sigma-c.com (Uwe Schnitker) wrote in message news:<30381f67.0404230150.707a33f4@posting.google. com>...
[color=blue]
> iii) deriving from classes which are not designed as base classes, like
> the standard library containers, is considered bad practice in C++,
> e.g. the lack of a virtual destructor may prove fatal[/color]
This idea is new to me .. do you have a reference where I can read
about it in more detail? In the past I have routinely derived classes
from std::vector and std::valarray, usually publicly, but sometimes
privately. I have done this when it seemed natural to do so in terms
of the "is-a" formalism for building class hierarchies. For example,
class positionArray : public std::vector<double> {
// some private data that is needed for manipulating the elements
// of the array
public:
positionArray(int size) : std::vector<double>(size) {
// whatever
}
void permute(); //
};
In my application positionArray is conceptually a vector of double, so
it makes sense to apply operations like subscripting directly, rather
than through an access function referencing a std::vector<double>
member. The positionArray class then would then typically also have a
few member functions for carrying out particular operations on the
underlying std::vector<double>.
I rarely use virtual functions or multiple inheritance, so the lack of
a virtual destructor has never been a problem for me .. although I
certainly see your point about that being a potential problem in the
more general case. Are there other weaknesses associated with
deriving from STL containers? If there are none, then it seems like
your advice above is perhaps a bit too restrictive.
Just my $0.02 ... Dave Moore | | | | re: Deriving a regular class from a template?
"Dave Moore" <dtmoore@rijnh.nl> wrote...[color=blue]
> schnitkerAffenschaukel@sigma-c.com (Uwe Schnitker) wrote in message[/color]
news:<30381f67.0404230150.707a33f4@posting.google. com>...[color=blue]
>[color=green]
> > iii) deriving from classes which are not designed as base classes,[/color][/color]
like[color=blue][color=green]
> > the standard library containers, is considered bad practice in[/color][/color]
C++,[color=blue][color=green]
> > e.g. the lack of a virtual destructor may prove fatal[/color]
> [...] Are there other weaknesses associated with
> deriving from STL containers? If there are none, then it seems like
> your advice above is perhaps a bit too restrictive.[/color]
No other weaknesses. The advice is usually directed at newbies so
that they don't get into a habit of deriving whenever they need to.
A note: I often find it helpful to derive privately. Then I can
control what functionality is exposed and I definitely prevent such
blunders as accidental polymorphic deletion.
Victor | | | | re: Deriving a regular class from a template?
Victor Bazarov wrote:[color=blue]
>
> "Dave Moore" <dtmoore@rijnh.nl> wrote...[color=green]
> > schnitkerAffenschaukel@sigma-c.com (Uwe Schnitker) wrote in message[/color]
> news:<30381f67.0404230150.707a33f4@posting.google. com>...[color=green]
> >[color=darkred]
> > > iii) deriving from classes which are not designed as base classes,[/color][/color]
> like[color=green][color=darkred]
> > > the standard library containers, is considered bad practice in[/color][/color]
> C++,[color=green][color=darkred]
> > > e.g. the lack of a virtual destructor may prove fatal[/color]
> > [...] Are there other weaknesses associated with
> > deriving from STL containers? If there are none, then it seems like
> > your advice above is perhaps a bit too restrictive.[/color]
>
> No other weaknesses. The advice is usually directed at newbies so
> that they don't get into a habit of deriving whenever they need to.
>
> A note: I often find it helpful to derive privately. Then I can
> control what functionality is exposed and I definitely prevent such
> blunders as accidental polymorphic deletion.
>
> Victor[/color]
So, if that is the case, then deriving from std containers should *NOT* be
labeled as a bad practice (bad design, etc.), but rather as an 'advanced
construct or idiom'.
I'm sure that _misnaming_ something 'bad practice/design' causes a lot more
problems that it is intended to solve. | | | | re: Deriving a regular class from a template?
"Julie" <julie@nospam.com> wrote[color=blue]
> Victor Bazarov wrote:[color=green]
> > A note: I often find it helpful to derive privately. Then I can
> > control what functionality is exposed and I definitely prevent such
> > blunders as accidental polymorphic deletion.
> >
> > Victor[/color]
>
> So, if that is the case, then deriving from std containers should *NOT* be
> labeled as a bad practice (bad design, etc.), but rather as an 'advanced
> construct or idiom'.[/color]
There's nothing advanced about the technique. It's simply error-prone, and so
should be avoided by anyone who doesn't understand the pitfalls and
limitations.
[color=blue]
> I'm sure that _misnaming_ something 'bad practice/design' causes a lot more
> problems that it is intended to solve.[/color]
It is a bad practice. The mitigating factor is that an expert will be able to
make bad practices work and will know how to limit the scope. Obviously, anyone
who has worked with a tool for a substantial amount of time will know how to
use otherwise inappropriate shortcuts to good effect, but that's an attribute
of the practitioner, not of the technique. I would certainly be more confident
of something unorthodox from Victor than I would from a completely orthodox
implementation from newbie-come-lately. That doesn't change that the practice
is frowned upon in a larger context. It's not because Evel Knievel can
successfully and reproducibly jump a motorcycle over a row of buses that
suddenly it becomes an acceptable practice for all bikers. It's an acceptable
practice for Evel Knievel.
Claudio Puviani | | | | re: Deriving a regular class from a template?
Claudio Puviani wrote:[color=blue]
>
> "Julie" <julie@nospam.com> wrote[color=green]
> > Victor Bazarov wrote:[color=darkred]
> > > A note: I often find it helpful to derive privately. Then I can
> > > control what functionality is exposed and I definitely prevent such
> > > blunders as accidental polymorphic deletion.
> > >
> > > Victor[/color]
> >
> > So, if that is the case, then deriving from std containers should *NOT* be
> > labeled as a bad practice (bad design, etc.), but rather as an 'advanced
> > construct or idiom'.[/color]
>
> There's nothing advanced about the technique. It's simply error-prone, and so
> should be avoided by anyone who doesn't understand the pitfalls and
> limitations.[/color]
The "pitfalls" are:
1. the behavior is undefined if you delete an object of a derived type
through a pointer to the base type.
The "limitations" are:
1. don't do that.
Of course, if you don't read documentation or don't design your code
before you write it you may well run afoul of these "pitfalls and
limitations". Too bad. Programming is a profession. If you can't pay
enough attention to do it right, don't do it at all.
--
Pete Becker
Dinkumware, Ltd. ( http://www.dinkumware.com) | | | | re: Deriving a regular class from a template?
"Pete Becker" <petebecker@acm.org> wrote[color=blue]
> Claudio Puviani wrote:[color=green]
> >
> > "Julie" <julie@nospam.com> wrote[color=darkred]
> > > Victor Bazarov wrote:
> > > > A note: I often find it helpful to derive privately. Then I can
> > > > control what functionality is exposed and I definitely prevent such
> > > > blunders as accidental polymorphic deletion.
> > > >
> > > > Victor
> > >
> > > So, if that is the case, then deriving from std containers should *NOT*[/color][/color][/color]
be[color=blue][color=green][color=darkred]
> > > labeled as a bad practice (bad design, etc.), but rather as an 'advanced
> > > construct or idiom'.[/color]
> >
> > There's nothing advanced about the technique. It's simply error-prone, and[/color][/color]
so[color=blue][color=green]
> > should be avoided by anyone who doesn't understand the pitfalls and
> > limitations.[/color]
>
> The "pitfalls" are:
>
> 1. the behavior is undefined if you delete an object of a derived type
> through a pointer to the base type.[/color]
I wasn't aware that a pointer to the base class could point to a class that
privately inherits from the base.
[color=blue]
>
> The "limitations" are:
>
> 1. don't do that.
>
> Of course, if you don't read documentation or don't design your code
> before you write it you may well run afoul of these "pitfalls and
> limitations". Too bad.[/color]
You'll notice in the rest of my post -- which you snipped -- that I refer to
the technique as a short-cut, not as a design choice. The whole point, which I
don't believe was at all obscure, was that as a rule, it's a bad practice. In
fact, I don't hint at it; I explicitly say, "It is a bad practice."
[color=blue]
> Programming is a profession. If you can't pay enough attention
> to do it right, don't do it at all.[/color]
I certainly hope this last part wasn't directed at me. You've been on this
newsgroup long enough that you've seen me bash many times the idea of
inheriting from classes that aren't designed for it. If I can homorously parody
the lecturing tone of the two last sentences: people who jump the gun shouldn't
own guns.
Claudio Puviani | | | | re: Deriving a regular class from a template?
Claudio Puviani wrote:[color=blue]
>[color=green]
> > Of course, if you don't read documentation or don't design your code
> > before you write it you may well run afoul of these "pitfalls and
> > limitations". Too bad.[/color]
>
> You'll notice in the rest of my post -- which you snipped -- that I refer to
> the technique as a short-cut, not as a design choice.[/color]
Sorry, I didn't mean to be as harsh as that sounded.
[color=blue]
> The whole point, which I
> don't believe was at all obscure, was that as a rule, it's a bad practice. In
> fact, I don't hint at it; I explicitly say, "It is a bad practice."[/color]
Yup, and I explicitly disagreed with that.
--
Pete Becker
Dinkumware, Ltd. ( http://www.dinkumware.com) | | | | re: Deriving a regular class from a template?
"Pete Becker" <petebecker@acm.org> wrote[color=blue]
> Claudio Puviani wrote:[color=green]
> >[color=darkred]
> > > Of course, if you don't read documentation or don't design your code
> > > before you write it you may well run afoul of these "pitfalls and
> > > limitations". Too bad.[/color]
> >
> > You'll notice in the rest of my post -- which you snipped -- that I refer[/color][/color]
to[color=blue][color=green]
> > the technique as a short-cut, not as a design choice.[/color]
>
> Sorry, I didn't mean to be as harsh as that sounded.[/color]
No problem. I'm hardly a diplomat myself. :-)
[color=blue][color=green]
> > The whole point, which I don't believe was at all obscure, was
> > that as a rule, it's a bad practice. In fact, I don't hint at it; I
> > explicitly say, "It is a bad practice."[/color]
>
> Yup, and I explicitly disagreed with that.[/color]
I'm confused now. When you said, "1. don't do that," I was under the impression
that you were agreeing with me. Are you saying that inheriting from inheriting
from standard containers is a good practice? If you are -- and we'd definitely
be in disagreement -- what did you mean by "don't do that"?
Claudio Puviani | | | | re: Deriving a regular class from a template?
Claudio Puviani wrote:[color=blue]
>
> I'm confused now. When you said, "1. don't do that," I was under the impression
> that you were agreeing with me. Are you saying that inheriting from inheriting
> from standard containers is a good practice? If you are -- and we'd definitely
> be in disagreement -- what did you mean by "don't do that"?
>[/color]
I mean what I said:
[color=blue]
> The "pitfalls" are:
>
> 1. the behavior is undefined IF YOU DELETE AN OBJECT OF A DERIVED TYPE
> THROUGH A POINTER TO THE BASE TYPE.
>
> The "limitations" are:
>
> 1. don't do that.[/color]
There are no nasty surprises here, certainly nothing to justify your
comparison to Evel Knievel.
--
Pete Becker
Dinkumware, Ltd. ( http://www.dinkumware.com) | | | | re: Deriving a regular class from a template?
"Pete Becker" <petebecker@acm.org> wrote[color=blue]
> Claudio Puviani wrote:[color=green]
> >
> > I'm confused now. When you said, "1. don't do that," I was under the[/color][/color]
impression[color=blue][color=green]
> > that you were agreeing with me. Are you saying that inheriting from[/color][/color]
inheriting[color=blue][color=green]
> > from standard containers is a good practice? If you are -- and we'd[/color][/color]
definitely[color=blue][color=green]
> > be in disagreement -- what did you mean by "don't do that"?
> >[/color]
>
> I mean what I said:
>[color=green]
> > The "pitfalls" are:
> >
> > 1. the behavior is undefined IF YOU DELETE AN OBJECT OF A DERIVED TYPE
> > THROUGH A POINTER TO THE BASE TYPE.
> >
> > The "limitations" are:
> >
> > 1. don't do that.[/color][/color]
Unfortunately, using pronouns tends to be ambiguous. The "that" in "don't do
that" could just as easily refered to inheriting from a non-polymorphic type. I
follow what you were saying now that "that" is bound to the preceding
statement. :-)
[color=blue]
> There are no nasty surprises here, certainly nothing to justify your
> comparison to Evel Knievel.[/color]
With private inheritance, I agree (and the "deleting through a pointer to the
base" admonition is also unnecessary since it can't be done). I wholeheartedly
stand by my comparison with respect to public inheritance from a
non-polymorphic type, however.
Claudio Puviani | | | | re: Deriving a regular class from a template?
Claudio Puviani wrote:[color=blue]
>
> "Pete Becker" <petebecker@acm.org> wrote[color=green]
> > There are no nasty surprises here, certainly nothing to justify your
> > comparison to Evel Knievel.[/color]
>
> With private inheritance, I agree (and the "deleting through a pointer to the
> base" admonition is also unnecessary since it can't be done).[/color]
It can be done. Think a little harder.
[color=blue]
> I wholeheartedly
> stand by my comparison with respect to public inheritance from a
> non-polymorphic type, however.
>[/color]
You need to cite facts; restating your opinion doesn't add any
information. What nasty surprises do you think are here that make this
too hazardous for most programmers to use?
--
Pete Becker
Dinkumware, Ltd. ( http://www.dinkumware.com) | | | | re: Deriving a regular class from a template?
"Pete Becker" <petebecker@acm.org> wrote[color=blue]
> Claudio Puviani wrote:[color=green]
> >
> > "Pete Becker" <petebecker@acm.org> wrote[color=darkred]
> > > There are no nasty surprises here, certainly nothing to justify your
> > > comparison to Evel Knievel.[/color]
> >
> > I wholeheartedly stand by my comparison with respect to public
> > inheritance from a non-polymorphic type, however.[/color]
>
> You need to cite facts; restating your opinion doesn't add any
> information. What nasty surprises do you think are here that make this
> too hazardous for most programmers to use?[/color]
I built up an argument, only to convince myself that you're right. Oh, there
were pitfalls all right (ex: changing the behavior in a non-virtual function
override), but they all also apply to inheritance from polymorphic types, so
it's inconsistent of me to single out non-polymorphic types for practices that
would be just as problematic elsewhere. In retrospect, those people I've seen
who had mangled projects by incorrectly inheriting from non-polymorphic types
weren't doing much better with the polymorphic types. In fact, they were doing
worse.
So consider my opinion retracted and my paranoia focused to a finer
grainularity.
Claudio Puviani | | | | re: Deriving a regular class from a template?
Claudio Puviani wrote:[color=blue]
>
> So consider my opinion retracted and my paranoia focused to a finer
> grainularity.
>[/color]
<g>
--
Pete Becker
Dinkumware, Ltd. ( http://www.dinkumware.com) | | | | re: Deriving a regular class from a template?
Claudio Puviani wrote:[color=blue]
>
> "Julie" <julie@nospam.com> wrote[color=green]
> > Victor Bazarov wrote:[color=darkred]
> > > A note: I often find it helpful to derive privately. Then I can
> > > control what functionality is exposed and I definitely prevent such
> > > blunders as accidental polymorphic deletion.
> > >
> > > Victor[/color]
> >
> > So, if that is the case, then deriving from std containers should *NOT* be
> > labeled as a bad practice (bad design, etc.), but rather as an 'advanced
> > construct or idiom'.[/color]
>
> There's nothing advanced about the technique. It's simply error-prone, and so
> should be avoided by anyone who doesn't understand the pitfalls and
> limitations.
>[color=green]
> > I'm sure that _misnaming_ something 'bad practice/design' causes a lot more
> > problems that it is intended to solve.[/color]
>
> It is a bad practice. The mitigating factor is that an expert will be able to
> make bad practices work and will know how to limit the scope. Obviously, anyone
> who has worked with a tool for a substantial amount of time will know how to
> use otherwise inappropriate shortcuts to good effect, but that's an attribute
> of the practitioner, not of the technique. I would certainly be more confident
> of something unorthodox from Victor than I would from a completely orthodox
> implementation from newbie-come-lately. That doesn't change that the practice
> is frowned upon in a larger context. It's not because Evel Knievel can
> successfully and reproducibly jump a motorcycle over a row of buses that
> suddenly it becomes an acceptable practice for all bikers. It's an acceptable
> practice for Evel Knievel.[/color]
I really don't get your point. At first, you say that it isn't an advanced
technique, then you go off to essentially say that it is acceptable for
experienced/expert users to use it???
Maybe you misinterpreted my intended meaning of advanced: intended to be used
by experienced programmers that recognize and understand the pitfalls and
limitations. | | | | re: Deriving a regular class from a template?
Pete Becker wrote:[color=blue]
>
> Claudio Puviani wrote:[color=green]
> >
> > "Julie" <julie@nospam.com> wrote[color=darkred]
> > > Victor Bazarov wrote:
> > > > A note: I often find it helpful to derive privately. Then I can
> > > > control what functionality is exposed and I definitely prevent such
> > > > blunders as accidental polymorphic deletion.
> > > >
> > > > Victor
> > >
> > > So, if that is the case, then deriving from std containers should *NOT* be
> > > labeled as a bad practice (bad design, etc.), but rather as an 'advanced
> > > construct or idiom'.[/color]
> >
> > There's nothing advanced about the technique. It's simply error-prone, and so
> > should be avoided by anyone who doesn't understand the pitfalls and
> > limitations.[/color]
>
> The "pitfalls" are:
>
> 1. the behavior is undefined if you delete an object of a derived type
> through a pointer to the base type.
>
> The "limitations" are:
>
> 1. don't do that.
>
> Of course, if you don't read documentation or don't design your code
> before you write it you may well run afoul of these "pitfalls and
> limitations". Too bad. Programming is a profession. If you can't pay
> enough attention to do it right, don't do it at all.[/color]
Pete, no one is advocating not reading the documentation or not designing
code. However, I'd like to know where in the documentation (i.e. standard) it
says that standard containers should not be derived from.
Second: if the answer is an unconditional "don't do that", then why is it
possible? What is the cost of making the containers 'sealed' (so that they
_can't_ be derived from)? If the cost is low or nonexistent, why didn't the
committee make that the case? | | | | re: Deriving a regular class from a template?
Pete Becker wrote:
[snip][color=blue]
> Of course, if you don't read documentation or don't design your code
> before you write it you may well run afoul of these "pitfalls and
> limitations". Too bad. Programming is a profession. If you can't pay
> enough attention to do it right, don't do it at all.[/color]
I hope that you aren't *serious* about this statement... If you are, then I
really hope that you and the rest of the committee are making concerted efforts
to make sure that everything is completely and thoroughly documented so that
there is no misinterpretation in the usage of *ANY* language construct or
library element.
[color=blue]
> If you can't pay
> enough attention to do it right, don't do it at all.[/color]
Pretty harsh words. Shall I go dig up all the corrections, retractions, etc.
from your column? | | | | re: Deriving a regular class from a template?
Julie wrote:[color=blue]
>
> Pete Becker wrote:[color=green]
> >
> > Of course, if you don't read documentation or don't design your code
> > before you write it you may well run afoul of these "pitfalls and
> > limitations". Too bad. Programming is a profession. If you can't pay
> > enough attention to do it right, don't do it at all.[/color]
>
> Pete, no one is advocating not reading the documentation or not designing
> code. However, I'd like to know where in the documentation (i.e. standard) it
> says that standard containers should not be derived from.[/color]
It doesn't. This discussion was about the derived types, not the base
types. As I said, because the standard containers don't have virtual
destructors, if you delete a derived object through a pointer to the
base, the behavior of the code is undefined.
[color=blue]
>
> Second: if the answer is an unconditional "don't do that", then why is it
> possible?[/color]
As with most undefined behavior, the reason is that it's too expensive
to check.
[color=blue]
> What is the cost of making the containers 'sealed' (so that they
> _can't_ be derived from)? If the cost is low or nonexistent, why didn't the
> committee make that the case?[/color]
There's little, if any, benefit from doing that, and there are
reasonable uses for it. What dangers do you see in deriving from
standard containers that would justify such a restriction?
--
Pete Becker
Dinkumware, Ltd. ( http://www.dinkumware.com) | | | | re: Deriving a regular class from a template?
Julie wrote:[color=blue]
>
> Pete Becker wrote:
> [snip][color=green]
> > Of course, if you don't read documentation or don't design your code
> > before you write it you may well run afoul of these "pitfalls and
> > limitations". Too bad. Programming is a profession. If you can't pay
> > enough attention to do it right, don't do it at all.[/color]
>
> I hope that you aren't *serious* about this statement... If you are, then I
> really hope that you and the rest of the committee are making concerted efforts
> to make sure that everything is completely and thoroughly documented so that
> there is no misinterpretation in the usage of *ANY* language construct or
> library element.[/color]
That is, indeed, a large part of what writing a standard is about.
With regard to the point under discussion, the standard (5.3.5/3) is
quite clear: "In the first alternative (delete object), if the static
type of the operand is different from its dynamic type, the static type
shall be a base class of the operand’s dynamic type and the static type
shall have a virtual destructor or the behavior is undefined."
--
Pete Becker
Dinkumware, Ltd. ( http://www.dinkumware.com) | | | | re: Deriving a regular class from a template?
Pete Becker wrote:[color=blue][color=green]
> > What is the cost of making the containers 'sealed' (so that they
> > _can't_ be derived from)? If the cost is low or nonexistent, why didn't the
> > committee make that the case?[/color]
>
> There's little, if any, benefit from doing that, and there are
> reasonable uses for it. What dangers do you see in deriving from
> standard containers that would justify such a restriction?[/color]
I'm lost.
I thought that we were talking about deriving from std containers, your answer
was "don't do that", now it looks like you are saying "there are reasonable
uses for it".
Please clarify. | | | | re: Deriving a regular class from a template?
Julie wrote:[color=blue]
>
> Pete Becker wrote:[color=green][color=darkred]
> > > What is the cost of making the containers 'sealed' (so that they
> > > _can't_ be derived from)? If the cost is low or nonexistent, why didn't the
> > > committee make that the case?[/color]
> >
> > There's little, if any, benefit from doing that, and there are
> > reasonable uses for it. What dangers do you see in deriving from
> > standard containers that would justify such a restriction?[/color]
>
> I'm lost.
>
> I thought that we were talking about deriving from std containers, your answer
> was "don't do that", now it looks like you are saying "there are reasonable
> uses for it".
>
> Please clarify.[/color]
I was talking about deleting derived objects through pointers to bases
without virtual destructors.
--
Pete Becker
Dinkumware, Ltd. ( http://www.dinkumware.com) | | | | re: Deriving a regular class from a template?
Pete Becker wrote:[color=blue]
>
> Julie wrote:[color=green]
> >
> > Pete Becker wrote:[color=darkred]
> > > > What is the cost of making the containers 'sealed' (so that they
> > > > _can't_ be derived from)? If the cost is low or nonexistent, why didn't the
> > > > committee make that the case?
> > >
> > > There's little, if any, benefit from doing that, and there are
> > > reasonable uses for it. What dangers do you see in deriving from
> > > standard containers that would justify such a restriction?[/color]
> >
> > I'm lost.
> >
> > I thought that we were talking about deriving from std containers, your answer
> > was "don't do that", now it looks like you are saying "there are reasonable
> > uses for it".
> >
> > Please clarify.[/color]
>
> I was talking about deleting derived objects through pointers to bases
> without virtual destructors.[/color]
Ok, that is understood.
Now, what are your feelings about deriving from std containers? A 'bad thing'
or 'advanced* technique'?
(*Advanced meaning for programmers that fully understand the ramifications of
such) | | | | re: Deriving a regular class from a template?
In message <408DABC7.9601801@nospam.com>, Julie <julie@nospam.com>
writes[color=blue]
>Pete Becker wrote:[color=green][color=darkred]
>> > What is the cost of making the containers 'sealed' (so that they
>> > _can't_ be derived from)? If the cost is low or nonexistent, why
>> >didn't the
>> > committee make that the case?[/color]
>>
>> There's little, if any, benefit from doing that, and there are
>> reasonable uses for it. What dangers do you see in deriving from
>> standard containers that would justify such a restriction?[/color]
>
>I'm lost.
>
>I thought that we were talking about deriving from std containers, your answer
>was "don't do that", now it looks like you are saying "there are reasonable
>uses for it".
>
>Please clarify.[/color]
FWIW I got the impression that PB's use of "don't do that" was not a
recommendation for how to code, but the "limitation" that should
therefore appear in the documentation - i.e. not "don't derive from
std:: containers" but "don't delete the result through base pointers".
The "pitfall" -- sliced deletion -- is countered by the "limitation" --
documentation forbids such deletion.
But maybe I'm more confused than the rest of you ;-(
--
Richard Herring |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,449 network members.
|