473,465 Members | 2,103 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Is it ok to inherit from vector?

Like this.

/********************/
class Card {
public:
Card() : rank(0), suit(0) {}
...
private:
int rank;
int suit;
};

class Cards : public vector<Card> {
public:
Cards();
...
};
/********************/

What about other STL types like string?

Thanks.
Jul 19 '05 #1
10 15171
Freddy Flares wrote:
Like this.

/********************/
class Card {
public:
Card() : rank(0), suit(0) {}
...
private:
int rank;
int suit;
};

class Cards : public vector<Card> {
public:
Cards();
...
};
/********************/

What about other STL types like string?


I wouldn't others would - see thread and make your own mind up.
http://groups.google.com/groups?as_u....uni-berlin.de

Jul 19 '05 #2
Freddy Flares wrote:
Like this.

/********************/
class Card {
public:
Card() : rank(0), suit(0) {}
...
private:
int rank;
int suit;
};

class Cards : public vector<Card> {
public:
Cards();
...
};
/********************/

What about other STL types like string?

Yes sure - no problems as long as any vector created with "Cards" is
destroyed from Cards's destructor.

Apart from this, the rest you'll hear is religion.

G

Jul 19 '05 #3
> Yes sure - no problems as long as any vector created with "Cards" is
destroyed from Cards's destructor.

Apart from this, the rest you'll hear is religion.


I agree. People like to quote ad nauseam about the lack of "virtual
destructors" and "concrete" classes (including Stroustrup himself) but it's
bunk no matter what the purists say (and with 20 years in the field I know
what I'm talking about). If done properly it's not a problem.
Jul 19 '05 #4
"Freddy Flares" <a@b.com> wrote in message
news:bo**********@sparta.btinternet.com...
Like this.

/********************/
class Card {
public:
Card() : rank(0), suit(0) {}
...
private:
int rank;
int suit;
};

class Cards : public vector<Card> {
public:
Cards();
...
};
/********************/

What about other STL types like string?

Thanks.


I don't think it's a good idea. Standard containers aren't really designed
to be base classes. I think generally that encapulation is a better paradigm
than inheritance unless you are designing a set of polymorphic classes. The
attractive thing about using inheritance with concrete types is that it can
save you a little typing. But encapsulation is more flexible and
maintainable IMHO.

Of course encapsulation and inheritance can both be a waste of time if your
only purpose is to add some functions. Just use functions! e.g.

typedef std::vector<Card> Deck;

void shuffle(Deck &);
Card deal(Deck &);
const Card& peek(const Deck &);

etc. This is actually a very clean design approach in a lot of cases.

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 19 '05 #5
On Wed, 12 Nov 2003 23:09:07 +0000 (UTC), Freddy Flares wrote:
class Cards : public vector<Card> { What about other STL types like string?


it's legal, but it's also dangerous, which means bad design. You'd
rather use encapsulation or free functions accepting (vector<Card>&)
parameter. Or if you really want to use inheritance, try this:

class Cards : protected vector<Card>{
using vector<Card>::size; // etc.

B.
Jul 19 '05 #6
On Thu, 13 Nov 2003 01:25:42 GMT, "John Brown" <_nospam@_nospam.com>
wrote:
Yes sure - no problems as long as any vector created with "Cards" is
destroyed from Cards's destructor.

Apart from this, the rest you'll hear is religion.


I agree. People like to quote ad nauseam about the lack of "virtual
destructors" and "concrete" classes (including Stroustrup himself) but it's
bunk no matter what the purists say (and with 20 years in the field I know
what I'm talking about). If done properly it's not a problem.


I disagree. I agree that the virtual destructor problem is a minor
thing. However, a much more major thing is the fact that Cards
probably has class invariants that vector<Cards> doesn't. For a start
there should perhaps be a separate Pack class and Hand class. Exposing
the whole vector interface may cause difficult to track down bugs in
the future, unless the Cards class is only used internally.

Deriving from a container is generally a "quick hack" that you end up
having to refactor in the long run anyway.

Tom
Jul 19 '05 #7
> I disagree. I agree that the virtual destructor problem is a minor
thing. However, a much more major thing is the fact that Cards
probably has class invariants that vector<Cards> doesn't. For a start
there should perhaps be a separate Pack class and Hand class. Exposing
the whole vector interface may cause difficult to track down bugs in
the future, unless the Cards class is only used internally.


Actually I agree with you. A restricted interface is typically necessary
though you can employ "using" statements to privatize public base class
members if you want (unbeknownst to many developers though it's an ugly
approach IMO). My real beef lies with those pedantic arguments that state
you absolutely must not do it:

a) Because of the virtual destructor issue
b) Because it's a "concrete" class not intended for further derivation

Well item a isn't an issue if properly controlled and item b is just a
pie-in-the-sky philosophy. Why should someone write a regular (non-member)
"toupper()" function for instance when it's cleaner to derive "MyString"
from "std::string" and implement a member function that does this instead.
It fits naturally into the OOP model and is therefore much cleaner
(especially for strings and vectors which are a staple of most projects).
Therefore, for a generic "vector" class it's ok to derive from it in many
circumstances (to add additional functionality in a controlled environment
for instance). When you need a restricted interface then you can consider
encapsulation.
Jul 19 '05 #8
"John Brown" <_nospam@_nospam.com> wrote in message
news:RT*****************@news04.bloor.is.net.cable .rogers.com...
I disagree. I agree that the virtual destructor problem is a minor
thing. However, a much more major thing is the fact that Cards
probably has class invariants that vector<Cards> doesn't. For a start
there should perhaps be a separate Pack class and Hand class. Exposing
the whole vector interface may cause difficult to track down bugs in
the future, unless the Cards class is only used internally.
Actually I agree with you. A restricted interface is typically necessary
though you can employ "using" statements to privatize public base class
members if you want (unbeknownst to many developers though it's an ugly
approach IMO). My real beef lies with those pedantic arguments that state
you absolutely must not do it:

a) Because of the virtual destructor issue
b) Because it's a "concrete" class not intended for further derivation

Well item a isn't an issue if properly controlled and item b is just a
pie-in-the-sky philosophy. Why should someone write a regular (non-member)
"toupper()" function for instance when it's cleaner to derive "MyString"
from "std::string" and implement a member function that does this instead.


Great. Now you have two versions of std::string floating around which differ
only in that one has a new member function. If I want to use your toupper
function but only have a std::string available I have to convert to a
different class just to use it. If I *don't* want to use your toupper
function I can't just ignore it -- for instance when somebody passes me a
MyString I have to look up what it is. And what if I wan't to add a second
function? Should I make a third string class? You have neatly outlined why
you should never do what you are advising.
It fits naturally into the OOP model and is therefore much cleaner
<groan> If this is your idea of cleanliness I hope you don't cook.
(especially for strings and vectors which are a staple of most projects).
Therefore, for a generic "vector" class it's ok to derive from it in many
circumstances (to add additional functionality in a controlled environment
for instance). When you need a restricted interface then you can consider
encapsulation.


I agree that some writers get carried away with pedantic arguments about
concrete base classes, but I think the rest of your argument is nonsense.

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 19 '05 #9
On Sat, 15 Nov 2003 15:46:57 GMT, John Brown wrote:
It fits naturally into the OOP model and is therefore much cleaner
(especially for strings and vectors which are a staple of most projects).
Therefore, for a generic "vector" class it's ok to derive from it in many


what you advise here is just against OOP. It is called
"strong coupling" and "mixing interface with implementation".
B.

Jul 19 '05 #10
John Brown wrote:
Yes sure - no problems as long as any vector created with "Cards" is
destroyed from Cards's destructor.

Apart from this, the rest you'll hear is religion.

I agree. People like to quote ad nauseam about the lack of "virtual
destructors" and "concrete" classes (including Stroustrup himself) but it's
bunk no matter what the purists say (and with 20 years in the field I know
what I'm talking about). If done properly it's not a problem.


You have to be sure that nobody ever decides to delete your
derived class via a base class pointer. As time goes on the
likelihood is that someone will, then you have undefined
behaviour.

Here is an example that results in segmentation error in
addition to the memory leak, if you uncomment the int b in A.

#include <vector>

class A {
int a;
// int b;
public:
virtual ~A() {};

};

class B : public std::vector<int> {
public:
virtual ~B() {};
};

class C: public A , public B {
public:
};

C* f()
{
new C;
}
int main()
{
std::vector<int>* b = f();
delete b;
return 0;
}

Jul 19 '05 #11

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

Similar topics

5
by: Ernst Murnleitner | last post by:
Hello, is it possible to derive from std::vector and derive also its iterator? If I do it like in the example below, I get a problem when I need the begin of the vector: begin() returns the...
3
by: cagenix | last post by:
I was running through a data structures book and I was curious if anyone could inform me of how to inherit the vector class to do a simple search and erase function. The example states: ...
0
by: cagenix | last post by:
I was running through a data structures book and I was curious if anyone could inform me of how to inherit the vector class to do a simple search and erase function. The example states: ...
11
by: TG | last post by:
Hi there. I'm trying to create a simple class called Vector which inherit from array. class Vector(array): def __init__(self,length): """initialize a vector of random floats of size length....
21
by: T.A. | last post by:
I understand why it is not safe to inherit from STL containers, but I have found (in SGI STL documentation) that for example bidirectional_iterator class can be used to create your own iterator...
3
by: Greg | last post by:
How do I inherit or templatise from a continer class, without having to reinterate (type) the member functions ?
4
by: nw | last post by:
Hi All, I currently have a vector of objects (lets call them MyObject). I want to perform various operations regularly on the whole vector, for example find the maximum, average, or operations...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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,...
0
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...
0
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,...
0
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
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,...
0
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...
0
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...

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.