473,692 Members | 1,863 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Inheriting a vector

Hi,
I want to have a vector like class with some additional functionality
(cosmetic one). So can I inherit a vector class to add the addition
function like,

CorresVector : public vector<Corres>{
public:
void addCorres(Corre s& c); //it do little more than push_back
function.
}
Or I need to do a composition to do it (i.e storing the vector inside
Corresvector & delegating the necessary functionality). I want to know
that whether in this case (inheriting) is allowed for containers, i.e
will the container will get freed when CorresVector gets destoryed (i.e
vector has a virtual destructor which gets called?)

abir

Sep 26 '06 #1
24 2945

toton wrote:
Hi,
I want to have a vector like class with some additional functionality
(cosmetic one). So can I inherit a vector class to add the addition
function like,

CorresVector : public vector<Corres>{
public:
void addCorres(Corre s& c); //it do little more than push_back
function.
}
Or I need to do a composition to do it (i.e storing the vector inside
Corresvector & delegating the necessary functionality). I want to know
that whether in this case (inheriting) is allowed for containers, i.e
will the container will get freed when CorresVector gets destoryed (i.e
vector has a virtual destructor which gets called?)
No, vector does not have a virtual destructor. It doesn't have any
virtual functions. You can inherit from a vector but you can't do so
polymorphically .

Sep 26 '06 #2
toton wrote:
Hi,
I want to have a vector like class with some additional functionality
(cosmetic one). So can I inherit a vector class to add the addition
function like,

CorresVector : public vector<Corres>{
public:
void addCorres(Corre s& c); //it do little more than push_back
function.
}
Or I need to do a composition to do it (i.e storing the vector inside
Corresvector & delegating the necessary functionality). I want to know
that whether in this case (inheriting) is allowed for containers, i.e
will the container will get freed when CorresVector gets destoryed (i.e
vector has a virtual destructor which gets called?)

abir
Hi abir,

std::vector does not have a virtual destructor.
But it would only need one, if you delete a CorresVector through a pointer
to a base class.

As for the question whether it is the "right" approach, use google and you
will find a lot of different opinions (see e.g.
http://www.thescripts.com/forum/thread63869.html).

Cheers,
Frank


Sep 26 '06 #3

Frank wrote:
toton wrote:
Hi,
I want to have a vector like class with some additional functionality
(cosmetic one). So can I inherit a vector class to add the addition
function like,

CorresVector : public vector<Corres>{
public:
void addCorres(Corre s& c); //it do little more than push_back
function.
}
Or I need to do a composition to do it (i.e storing the vector inside
Corresvector & delegating the necessary functionality). I want to know
that whether in this case (inheriting) is allowed for containers, i.e
will the container will get freed when CorresVector gets destoryed (i.e
vector has a virtual destructor which gets called?)

abir

Hi abir,

std::vector does not have a virtual destructor.
But it would only need one, if you delete a CorresVector through a pointer
to a base class.

As for the question whether it is the "right" approach, use google and you
will find a lot of different opinions (see e.g.
http://www.thescripts.com/forum/thread63869.html).
I have a Session class which stores the CorresVector, not a pointer or
reference. and Session class destructor will thus automatically call
CorresVector. Hence there is no ploymorphic behavior. I hope there will
not be any memory leak therefore.
Otherwise it is pain to delegate a lot of method including container
traits & iterators.
Religion is definitely a question, may think later of delegating (or
protected inheritence) if my class sufficiently differs from vector or
any other misuse question comes (I know Java Stack is inherited from
Vector ! ).
Cheers,
Frank
Sep 26 '06 #4

Frank wrote:
toton wrote:
Hi,
I want to have a vector like class with some additional functionality
(cosmetic one). So can I inherit a vector class to add the addition
function like,

CorresVector : public vector<Corres>{
public:
void addCorres(Corre s& c); //it do little more than push_back
function.
}
Or I need to do a composition to do it (i.e storing the vector inside
Corresvector & delegating the necessary functionality). I want to know
that whether in this case (inheriting) is allowed for containers, i.e
will the container will get freed when CorresVector gets destoryed (i.e
vector has a virtual destructor which gets called?)

abir

Hi abir,

std::vector does not have a virtual destructor.
But it would only need one, if you delete a CorresVector through a pointer
to a base class.

As for the question whether it is the "right" approach, use google and you
will find a lot of different opinions (see e.g.
http://www.thescripts.com/forum/thread63869.html).
I have a Session class which stores the CorresVector, not a pointer or
reference. and Session class destructor will thus automatically call
CorresVector. Hence there is no ploymorphic behavior. I hope there will
not be any memory leak therefore.
Otherwise it is pain to delegate a lot of method including container
traits & iterators.
Religion is definitely a question, may think later of delegating (or
protected inheritence) if my class sufficiently differs from vector or
any other misuse question comes (I know Java Stack is inherited from
Vector ! ).
Thanks for quick answer.
Cheers,
Frank
Sep 26 '06 #5

toton wrote:
Hi,
I want to have a vector like class with some additional functionality
(cosmetic one). So can I inherit a vector class to add the addition
function like,

CorresVector : public vector<Corres>{
public:
void addCorres(Corre s& c); //it do little more than push_back
function.
}
Or I need to do a composition to do it (i.e storing the vector inside
Corresvector & delegating the necessary functionality). I want to know
that whether in this case (inheriting) is allowed for containers, i.e
will the container will get freed when CorresVector gets destoryed (i.e
vector has a virtual destructor which gets called?)

abir
You should not derive from STL container classes. Their destructors are
not virtual.
Although, in my book, composition can be a form of private inheritence.
Why not template the class? In your example, if element class Corres,
whatever that is, overloads the global op<<, you can add features as
shown below. Note that both primitive int and class std::string already
have an overloaded operator<<.

The point here is that if you are going to compose with a std::vector,
do it to add features, otherwise you would not need to wrap the
container.
How you do that is not very complicated:

a) learn how to declare and use templates
b) pass by reference
c) dependant types need the typename keyword
d) overload operators

#include <iostream>
#include <ostream>
#include <string>
#include <vector>

template< typename T >
class Vector
{
std::vector< T vt;
public:
Vector() : vt() { } // an empty vector of TsSince primitive types
like int and other classes like std::string already have an overload
for global op<<, i can iterate through the elements simply by writing:

std::cout << name_of_contain er;
~Vector() { }
/* member functions */
size_t size() const { return vt.size(); }
void push_back( const T& r_t ) { vt.push_back( r_t ); }
/* friend op */
friend
std::ostream&
operator<<( std::ostream& os, Vector< T >& r_v )
{ // std::vector<T>: :iterator is a dependant type
typedef typename std::vector< T >::iterator VIter;
VIter iter = r_v.vt.begin();
for ( iter; iter != r_v.vt.end(); ++iter )
{
os << *iter << std::endl;
}
return os;
}
};

int main()
{
Vector< int integers;
for ( int n = 0; n < 5; ++n )
{
integers.push_b ack( n );
}
std::cout << integers; // op<< overload

Vector< std::string strings;
strings.push_ba ck( "first string" );
strings.push_ba ck( "second string" );
strings.push_ba ck( "third string" );
strings.push_ba ck( "fourth string" );
std::cout << strings; // op<< overload

return 0;
}

/*
0
1
2
3
4
first string
second string
third string
fourth string
*/

Sep 26 '06 #6

Salt_Peter wrote:
toton wrote:
Hi,
I want to have a vector like class with some additional functionality
(cosmetic one). So can I inherit a vector class to add the addition
function like,

CorresVector : public vector<Corres>{
public:
void addCorres(Corre s& c); //it do little more than push_back
function.
}
Or I need to do a composition to do it (i.e storing the vector inside
Corresvector & delegating the necessary functionality). I want to know
that whether in this case (inheriting) is allowed for containers, i.e
will the container will get freed when CorresVector gets destoryed (i.e
vector has a virtual destructor which gets called?)

abir

You should not derive from STL container classes. Their destructors are
not virtual.
Although, in my book, composition can be a form of private inheritence.
Why not template the class? In your example, if element class Corres,
whatever that is, overloads the global op<<, you can add features as
shown below. Note that both primitive int and class std::string already
have an overloaded operator<<.

The point here is that if you are going to compose with a std::vector,
do it to add features, otherwise you would not need to wrap the
container.
How you do that is not very complicated:

a) learn how to declare and use templates
b) pass by reference
c) dependant types need the typename keyword
d) overload operators

#include <iostream>
#include <ostream>
#include <string>
#include <vector>

template< typename T >
class Vector
{
std::vector< T vt;
public:
Vector() : vt() { } // an empty vector of TsSince primitive types
like int and other classes like std::string already have an overload
for global op<<, i can iterate through the elements simply by writing:

std::cout << name_of_contain er;
~Vector() { }
/* member functions */
size_t size() const { return vt.size(); }
void push_back( const T& r_t ) { vt.push_back( r_t ); }
/* friend op */
friend
std::ostream&
operator<<( std::ostream& os, Vector< T >& r_v )
{ // std::vector<T>: :iterator is a dependant type
typedef typename std::vector< T >::iterator VIter;
VIter iter = r_v.vt.begin();
for ( iter; iter != r_v.vt.end(); ++iter )
{
os << *iter << std::endl;
}
return os;
}
};

int main()
{
Vector< int integers;
for ( int n = 0; n < 5; ++n )
{
integers.push_b ack( n );
}
std::cout << integers; // op<< overload

Vector< std::string strings;
strings.push_ba ck( "first string" );
strings.push_ba ck( "second string" );
strings.push_ba ck( "third string" );
strings.push_ba ck( "fourth string" );
std::cout << strings; // op<< overload

return 0;
}

/*
0
1
2
3
4
first string
second string
third string
fourth string
*/
This is the other option which I thought (and mentioned in my first
post). Using delegate is always better, I think. It both protects
security, and makes a cleaner interface (I had mentioned like Java
Vector & Stack). And templating Vector is not usefull for my case, as I
am going to use only and only CorresVector where some additional
methods are there, to perform some additional job, and may want to
build a library from that directly for my core engine part of the
application. Not that it can not be done otherway, (like performing
the tasks after push_back operation, say some notification event
handling) but assigning the tasks in the operation itself secures code.

However unlike the code you presented, I need many features of vector
rather than just push_back. Most importantly, I need the iterator
functionality, and want to apply many stl algorithms to CorresVector
just like vector. That says I need to delegate many more functions
rather than size & push_back( say aoo of the iterator traits, const &
non const vercion of begin end etc, reserve, indexing operators, at and
others). It is not difficult, it is tedious!
And in code CorresVector is going to be used only one place, i.e inside
Session class, like,
class Session{
private:
CorresVector _corres;
};
and some reference get methods (const & non const). There is no other
place where it will be used (there is no other place there it can be
used also :) ). Thus I think it will not cause any memory leak in this
particular case(i.e not freeing the elements on destruction). Session
class has a virtual destructor, and hence it will always get destroyed
even when inheriting & storing in SessionManager (a singleton) like
FileSession, OnlineSession etc.
Can you say a yes/no about risk to this specific case?
For general case, I like your answer, and sooner or later will
implement it.
btw Corres means Correspondence (a special kind of distance structure)

Thanks for the reply & the worning.

Sep 26 '06 #7

Salt_Peter wrote:
toton wrote:
Hi,
I want to have a vector like class with some additional functionality
(cosmetic one). So can I inherit a vector class to add the addition
function like,

You should not derive from STL container classes. Their destructors are
not virtual.
That should read "you should not polymorphically delete objects of
types derived from STL container classes. STL container classes do not
have virtual destructors."
Although, in my book, composition can be a form of private inheritence.
Why not template the class? In your example, if element class Corres,
whatever that is, overloads the global op<<, you can add features as
shown below. Note that both primitive int and class std::string already
have an overloaded operator<<.

The point here is that if you are going to compose with a std::vector,
do it to add features, otherwise you would not need to wrap the
container.
How you do that is not very complicated:

a) learn how to declare and use templates
b) pass by reference
c) dependant types need the typename keyword
d) overload operators

#include <iostream>
#include <ostream>
#include <string>
#include <vector>

template< typename T >
class Vector
{
std::vector< T vt;
public:
Vector() : vt() { } // an empty vector of TsSince primitive types
like int and other classes like std::string already have an overload
for global op<<, i can iterate through the elements simply by writing:

std::cout << name_of_contain er;
~Vector() { }
/* member functions */
size_t size() const { return vt.size(); }
void push_back( const T& r_t ) { vt.push_back( r_t ); }
/* friend op */
friend
std::ostream&
operator<<( std::ostream& os, Vector< T >& r_v )
{ // std::vector<T>: :iterator is a dependant type
typedef typename std::vector< T >::iterator VIter;
VIter iter = r_v.vt.begin();
for ( iter; iter != r_v.vt.end(); ++iter )
{
os << *iter << std::endl;
}
return os;
}
};
How is that class superior to this? If used with your program below it
produces the same output.

template <typename T>
class Vector : public std::vector<T>
{
friend std::ostream& operator<<(std: :ostream& os, Vector< T >& r_v)
{
typedef typename std::vector< T >::iterator VIter;
VIter iter = r_v.begin();
for ( iter; iter != r_v.end(); ++iter )
{
os << *iter << std::endl;
}
return os;
}
};
int main()
{
Vector< int integers;
for ( int n = 0; n < 5; ++n )
{
integers.push_b ack( n );
}
std::cout << integers; // op<< overload

Vector< std::string strings;
strings.push_ba ck( "first string" );
strings.push_ba ck( "second string" );
strings.push_ba ck( "third string" );
strings.push_ba ck( "fourth string" );
std::cout << strings; // op<< overload
But your class can't do this unless you go back and change it.

strings.pop_bac k();
std::cout << strings;
>
return 0;
}

/*
0
1
2
3
4
first string
second string
third string
fourth string
first string
second string
third string
*/
Gavin Deane

Sep 26 '06 #8
Noah Roberts wrote:
toton wrote:
>Hi,
I want to have a vector like class with some additional functionality
(cosmetic one). So can I inherit a vector class to add the addition
function like,

CorresVector : public vector<Corres>{
public:
void addCorres(Corre s& c); //it do little more than push_back
function.
}
Or I need to do a composition to do it (i.e storing the vector inside
Corresvector & delegating the necessary functionality). I want to know
that whether in this case (inheriting) is allowed for containers, i.e
will the container will get freed when CorresVector gets destoryed (i.e
vector has a virtual destructor which gets called?)

No, vector does not have a virtual destructor. It doesn't have any
virtual functions. You can inherit from a vector but you can't do so
polymorphically .
But that's really two different questions. Yes, when CorresVector gets
destroyed, its base will, too. No, if you have a pointer to the base and
you delete that, you have no guarantees of what will happen, because the
base type does not have a virtual destructor.

--

-- Pete

Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." For more information about this book, see
www.petebecker.com/tr1book.
Sep 26 '06 #9

Gavin Deane wrote:
Salt_Peter wrote:
toton wrote:
Hi,
I want to have a vector like class with some additional functionality
(cosmetic one). So can I inherit a vector class to add the addition
function like,
You should not derive from STL container classes. Their destructors are
not virtual.

That should read "you should not polymorphically delete objects of
types derived from STL container classes. STL container classes do
not
have virtual destructors."
yes, of course. But isn't that the goal here?
Otherwise, why bother inheriting from a std::vector?
>
Although, in my book, composition can be a form of private inheritence.
Why not template the class? In your example, if element class Corres,
whatever that is, overloads the global op<<, you can add features as
shown below. Note that both primitive int and class std::string already
have an overloaded operator<<.

The point here is that if you are going to compose with a std::vector,
do it to add features, otherwise you would not need to wrap the
container.
How you do that is not very complicated:

a) learn how to declare and use templates
b) pass by reference
c) dependant types need the typename keyword
d) overload operators

#include <iostream>
#include <ostream>
#include <string>
#include <vector>

template< typename T >
class Vector
{
std::vector< T vt;
public:
Vector() : vt() { } // an empty vector of TsSince primitive types
like int and other classes like std::string already have an overload
for global op<<, i can iterate through the elements simply by writing:

std::cout << name_of_contain er;
~Vector() { }
/* member functions */
size_t size() const { return vt.size(); }
void push_back( const T& r_t ) { vt.push_back( r_t ); }
/* friend op */
friend
std::ostream&
operator<<( std::ostream& os, Vector< T >& r_v )
{ // std::vector<T>: :iterator is a dependant type
typedef typename std::vector< T >::iterator VIter;
VIter iter = r_v.vt.begin();
for ( iter; iter != r_v.vt.end(); ++iter )
{
os << *iter << std::endl;
}
return os;
}
};

How is that class superior to this? If used with your program below it
produces the same output.
My class is not superior in any way unless there is a need to protect
the internals or if polymorphism is involved.
>
template <typename T>
class Vector : public std::vector<T>
{
If you inherit publicly, friend is no longer required, the std::vector
is directly accessible.
friend std::ostream& operator<<(std: :ostream& os, Vector< T >& r_v)
{
typedef typename std::vector< T >::iterator VIter;
VIter iter = r_v.begin();
for ( iter; iter != r_v.end(); ++iter )
{
os << *iter << std::endl;
}
return os;
}
};
or

#include <iostream>
#include <ostream>
#include <string>
#include <vector>
#include <iterator>

template< typename T >
class Vector : public std::vector< T >
{
};

template< typename T >
std::ostream&
operator<<( std::ostream& os, Vector< T >& r_v )
{
std::copy( r_v.begin(),
r_v.end(),
std::ostream_it erator< T ( std::cout , "\n") );
}

Which again brings us right back to the crux of the issue. In such a
case, why bother inheriting from std::vector? What is the reason?
>
int main()
{
Vector< int integers;
for ( int n = 0; n < 5; ++n )
{
integers.push_b ack( n );
}
std::cout << integers; // op<< overload

Vector< std::string strings;
strings.push_ba ck( "first string" );
strings.push_ba ck( "second string" );
strings.push_ba ck( "third string" );
strings.push_ba ck( "fourth string" );
std::cout << strings; // op<< overload

But your class can't do this unless you go back and change it.

strings.pop_bac k();
std::cout << strings;
Thats obvious. The rest of the interface was not implemented.
>
Gavin Deane
Sep 26 '06 #10

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

Similar topics

26
10721
by: BCC | last post by:
Hi, A colleague has some code like this: class CMyObject { // Bunch of Member functions } class CMyObjectList: public std::vector<CMyObject> {
4
1552
by: Thomas Matthews | last post by:
Hi, I have a class Record which is a container of fields. I have overloaded operator to return a pointer to a Field: class Field; // Forward declaration class Record { public: Field * operator(unsigned int index); };
3
1464
by: toton | last post by:
Hi, If I inherit some template class to form another template class, do the member functions from the parent class automatically comes to the child class, or I need to write something like using boost::vector<T,Alloc>::begin; etc (to get begin() and other functions). Similarly all the base class typedef's automatically come to the derived class or I need to explicitly say typedef typename std::vector<T, Alloc>::pointer pointer;
0
8603
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
9083
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
8800
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6459
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
5818
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4323
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
2972
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
2
2237
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
1957
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.