| View previous topic :: View next topic |
| Author |
Message |
Valery Aronov Guest
|
Posted: Thu Jul 28, 2005 12:36 pm Post subject: deriving from a std::vector |
|
|
I needed to have an operator->() defined for std::vector (I had an
N-dimensional vector of vectors constructed out of it), so I just
derived VectorWithArrow from std:vector with this single extra method,
even the latter is not meant to be used as a base class.
VectorWithArrow was used in a very certain context - always placed on
the stack, never addressed via pointers. The derivation is dataless.
Using composition instead just looks like too much of code (considering
vector's rich interface) without any clear benefit.
What can go wrong with this design?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
tony_in_da_uk@yahoo.co.uk Guest
|
Posted: Thu Jul 28, 2005 3:07 pm Post subject: Re: deriving from a std::vector |
|
|
You can put a team of less able programmers out of work. Cheers - Tony
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gene Bushuyev Guest
|
Posted: Fri Jul 29, 2005 1:13 am Post subject: Re: deriving from a std::vector |
|
|
"Valery Aronov" <valerka (AT) gmail (DOT) com> wrote
| Quote: | I needed to have an operator->() defined for std::vector (I had an
N-dimensional vector of vectors constructed out of it), so I just
derived VectorWithArrow from std:vector with this single extra method,
even the latter is not meant to be used as a base class.
VectorWithArrow was used in a very certain context - always placed on
the stack, never addressed via pointers. The derivation is dataless.
Using composition instead just looks like too much of code (considering
vector's rich interface) without any clear benefit.
What can go wrong with this design?
|
What can go wrong? - When somebody decides to use your vector
polymorphically.
What C++ language design achieved is public derivation in order to be reused
(ISA). What it didn't achieve is the ability to reuse easily. If there was a
possibility of adding composition with automatic adding of interface then
many cases like yours would be covered. As a result people choose easy road
of derivation instead of composition and repeating every single function of
the public interface. Wouldn't it be nice to have something like this:
struct VectorWithArrow : static vector<int>
{
int* operator->();
};
where "static" keyword would prevent polymorphic use, virtual functions
overriding, etc.
- gene
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Tom Widmer Guest
|
Posted: Fri Jul 29, 2005 12:48 pm Post subject: Re: deriving from a std::vector |
|
|
Not much. However, adding operator-> to std::vector seems to be a very
strange thing to want to do, and is likely to surprise anyone who looks
at the code in the future. Deriving from std::vector will also likely
surprise anyone looking at the code. Why do you need the operator->
overload? Why can't you use a free function instead?
Tom
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Valery Aronov Guest
|
Posted: Fri Jul 29, 2005 2:51 pm Post subject: Re: deriving from a std::vector |
|
|
What do you mean, Tony?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Valery Aronov Guest
|
Posted: Fri Jul 29, 2005 2:52 pm Post subject: Re: deriving from a std::vector |
|
|
There are no virtual functions in VectorWithArrow (nor in std::vector),
so to use it polymorphycally someone has to add them, to derive new
classes, but that would be a separate crazy design which the suggested
one has nothing to do with.
An attempt to use it below will fail to compile foo:
#include <vector>
using namespace std;
struct VectorWithArrow : vector<int> {
int operator->() { return 1; }
};
int bar(VectorWithArrow* p) {
return p->operator->();
}
int foo(vector<int>* p) {
return p->operator->();
}
int main() {
VectorWithArrow vwa;
vwa.resize(10);
int i = foo(&vwa);
int j = bar(&vwa);
int k = vwa.operator->();
return 0;
}
Hardly a problem. Is there any problem? Does not it mean that it is OK
to do what I've done?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Valery Aronov Guest
|
Posted: Fri Jul 29, 2005 2:55 pm Post subject: Re: deriving from a std::vector |
|
|
We have N-dimensional nested vectors (VectorWithArrow) and allow the
following:
class Model {
int age;
};
NestedVector<Model, 5> nv;
nv[2][1]->age = 50;
It sets age to 50 for every instance of Model in the subtree with the
root at [2][1].
Note that operator->() is not overloaded but added - it is not defined
for a vector.
VectorWithArrow is for this very specific context and the reader would
not be that surprised is she reads comments.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gene Bushuyev Guest
|
Posted: Fri Jul 29, 2005 5:47 pm Post subject: Re: deriving from a std::vector |
|
|
"Valery Aronov" <valerka (AT) gmail (DOT) com> wrote
| Quote: | There are no virtual functions in VectorWithArrow (nor in std::vector),
so to use it polymorphycally someone has to add them, to derive new
classes, but that would be a separate crazy design which the suggested
one has nothing to do with.
|
You didn't understand my reply. I said "decides" to use polymorphically, not
that it was "designed" to be used polymorphically. By publicly deriving you
create ISA relationship that is not true in reality. Imagine somebody may
write:
void Delete(vector<int>* v) { delete v; }
....
VectorWithArrow* v = new VectorWithArrow;
....
Delete(v); // kaboom!
- gene
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
leimy2k@gmail.com Guest
|
Posted: Sat Jul 30, 2005 10:09 am Post subject: Re: deriving from a std::vector |
|
|
Gene Bushuyev wrote:
| Quote: | "Valery Aronov" <valerka (AT) gmail (DOT) com> wrote in message
news:1122643910.926781.137300 (AT) g49g2000cwa (DOT) googlegroups.com...
There are no virtual functions in VectorWithArrow (nor in std::vector),
so to use it polymorphycally someone has to add them, to derive new
classes, but that would be a separate crazy design which the suggested
one has nothing to do with.
You didn't understand my reply. I said "decides" to use polymorphically, not
that it was "designed" to be used polymorphically. By publicly deriving you
create ISA relationship that is not true in reality. Imagine somebody may
write:
|
Sure, but that's true of any class at all isn't it? Someone might
decide to use STL classes polymorphically and it's just as bad an idea
as it is for someone to use VectorWithArrow polymorphically .
One could argue that every class needs to have a virtual destructor in
order to safeguard against the possibility that someone might decide to
use the class as it wasn't intended. This would be going too far I
think, and if you really want a language with that sort of strictness
in how classes are written, then you don't want C++ .
I know, Scott Meyers and others said "don't do it". But at the end of
the day that advice is just that... advice . This doesn't mean you
are writing bad code, as long as you understand and make sure the users
of your code understand the intent of use.
I sometimes think part of what's "wrong" with C++ is not just the
complexity of the language and the loopholes you can get caught in, but
that some people sometimes get caught up too much in a "way" of coding
it dogmatically. The language wouldn't be as flexible as it is if it
didn't allow for certain freedoms. Yes, the advice given by the
masters is incredibly useful and should probably be followed 9/10 times
[if not more], but they aren't going to write/maintain your code for
you :)
Dave
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Sun Jul 31, 2005 11:44 am Post subject: Re: deriving from a std::vector |
|
|
[email]leimy2k (AT) gmail (DOT) com[/email] <leimy2k (AT) gmail (DOT) com> wrote:
| Quote: | I know, Scott Meyers and others said "don't do it". But at the end of
the day that advice is just that... advice . This doesn't mean you
are writing bad code, as long as you understand and make sure the users
of your code understand the intent of use.
|
In the context of classical runtime polymorphism via virtuals and
public inheritance, its fine advice, but in more general terms its like
'always have only one return point in a function' advice. If a user of
your clasess uses your classes out of context then its his problem. C++
does more than classical OOP on top of C. This advice taken as 'always
yse' removes common template idioms like CRTP or expression templates
from your arsenal. I think this advice is like SESE, meant for a
different time.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Valery Aronov Guest
|
Posted: Sun Jul 31, 2005 11:45 am Post subject: Re: deriving from a std::vector |
|
|
Very true, Dave. I think "... publicly deriving you create ISA
relationship ... " which Gene quoted is one of such useful rules, but
the legitimate exceptions should be acceptable. Not that there are many
of them ...
Then I can add a private or not defined
static void * operator new(size_t size);
to VectorWithArrow.
Now is not it a good idea NOT to have a notion of a "final" class?
Otherwise std::vector would've likely been the final one and would not
allow me to do what I did that easily. Is not it a power and a
pragmatism of C++ the language that exceptions from the rules are not
that strictly enforced ... sometimes.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Valery Aronov Guest
|
Posted: Mon Aug 01, 2005 8:02 am Post subject: Re: deriving from a std::vector |
|
|
O-o-o-ps! I can't have operator new() undefined as I suggested, because
std allocates the space on the heap. Still until VectorWithArrow is
dataless the design is safe.
I am correspoding with myself using this newsgroup ;-)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
tony_in_da_uk@yahoo.co.uk Guest
|
Posted: Mon Aug 08, 2005 3:11 pm Post subject: Re: deriving from a std::vector |
|
|
Hi Valery. I meant that many programmers happily spend weeks trying to
find the perfect way to implement something, and end up turning a small
problem into something much bigger. While your approach has some minor
drawbacks (as mentioned in the other posts), they're very rarely
relevant. Your approach is practical, concise, and saves a lot of
work. Entirely sensible to run with it in 99% of cases. - Tony
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|