473,394 Members | 1,773 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

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 15169
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...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
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
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...

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.