PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > How to use the iterator from base class in a derived class?
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
How to use the iterator from base class in a derived class?

Réponse
 
LinkBack Outils de la discussion
Vieux 18/10/2007, 08h29   #1
wangxiaohu
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut How to use the iterator from base class in a derived class?

I am trying to write a class myVector based on std::vector and add
only a sort method. The sort method needs to access the array stored
in the base class using iterator. I have following draft code. However
it never compile. Can anyone take a look and tell me how to fix it?
Thanks!

#include <vector>
#include <iostream>

using namespace std;

template <typename T> class myVector : public vector<T>
{
public:
void Sort();
};

template <typename T> void Sort<T>::Sort()
{
if (this.size() < 2)
{
return;
}

vector<T>::iterator i;

for (i = this.begin(); i != this.end(); i++)
{
//rest part ignored....
}
}

  Réponse avec citation
Vieux 18/10/2007, 09h04   #2
Erik Wikström
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to use the iterator from base class in a derived class?

On 2007-10-18 09:29, wangxiaohu wrote:
> I am trying to write a class myVector based on std::vector and add
> only a sort method. The sort method needs to access the array stored
> in the base class using iterator. I have following draft code. However
> it never compile. Can anyone take a look and tell me how to fix it?
> Thanks!
>
> #include <vector>
> #include <iostream>
>
> using namespace std;
>
> template <typename T> class myVector : public vector<T>


The general advice is to not inherit from the standard containers,
instead create a class that wraps the container.

> {
> public:
> void Sort();
> };
>
> template <typename T> void Sort<T>::Sort()


template <typename T> void <myVector<T>::sort()

> {
> if (this.size() < 2)


this->size()

This is a pointer to the current object, you need to use the dereference
operator (->) when accessing members of the current object.

--
Erik Wikström
  Réponse avec citation
Vieux 18/10/2007, 09h22   #3
Kai-Uwe Bux
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to use the iterator from base class in a derived class?

wangxiaohu wrote:

> I am trying to write a class myVector based on std::vector and add
> only a sort method.


BadIdea(tm). That is abuse of inheritance. You should use a free standing
function instead:

template < typename T, typename A >
void sort_vector ( std::vector<T,A> & sequence ) {
std::sort( sequence.begin(), sequence.end() );
}

or maybe even more generic:

template < typename Container >
void sort_sequence ( Container & sequence ) {
std::sort( sequence.begin(), sequence.end() );
}

or with a concept check:

template < typename Container >
void sort_sequence
( Container & sequence,
typename enable_if
< is_sequence< Container >::value, void* >::type = 0 ) {
std::sort( sequence.begin(), sequence.end() );
}


There are some cases where public inheritance from std::vector<> is
justified. This does not look like one of them.


> The sort method needs to access the array stored
> in the base class using iterator. I have following draft code. However
> it never compile. Can anyone take a look and tell me how to fix it?
> Thanks!
>
> #include <vector>
> #include <iostream>
>
> using namespace std;


Don't put using directives in header files. Your decision to pull all
identifiers from the standard namespace is inflicted upon every user of
your class. That is very intrusive.


> template <typename T> class myVector : public vector<T>
> {
> public:
> void Sort();
> };
>
> template <typename T> void Sort<T>::Sort()


Shouldn't that be something like

template <typename T>
void myVector::Sort()


> {
> if (this.size() < 2)
> {
> return;
> }
>
> vector<T>::iterator i;


You would need to say

typename std::vector<T>::iterator i;

The keyword here is "dependent name".


>
> for (i = this.begin(); i != this.end(); i++)
> {
> //rest part ignored....
> }
> }


BTW: why are you doing your own sort algorithm? any why only for vectors? It
is _very_ hard to beat std::sort() from the header <algorithm>.


Best

Kai-Uwe Bux
  Réponse avec citation
Vieux 18/10/2007, 10h08   #4
wangxiaohu
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to use the iterator from base class in a derived class?

I just want to see if I can add a Sort() method to the existing vector
container.

What you've shown is write a individual function, which does work for
the purpose, but does not answer my question.

But really thanks to your detailed example!

wxh

On 10 18 , 1 22 , Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> wangxiaohu wrote:
> > I am trying to write a class myVector based on std::vector and add
> > only a sort method.

>
> BadIdea(tm). That is abuse of inheritance. You should use a free standing
> function instead:
>
> template < typename T, typename A >
> void sort_vector ( std::vector<T,A> & sequence ) {
> std::sort( sequence.begin(), sequence.end() );
> }
>
> or maybe even more generic:
>
> template < typename Container >
> void sort_sequence ( Container & sequence ) {
> std::sort( sequence.begin(), sequence.end() );
> }
>
> or with a concept check:
>
> template < typename Container >
> void sort_sequence
> ( Container & sequence,
> typename enable_if
> < is_sequence< Container >::value, void* >::type = 0 ) {
> std::sort( sequence.begin(), sequence.end() );
> }
>
> There are some cases where public inheritance from std::vector<> is
> justified. This does not look like one of them.
>
> > The sort method needs to access the array stored
> > in the base class using iterator. I have following draft code. However
> > it never compile. Can anyone take a look and tell me how to fix it?
> > Thanks!

>
> > #include <vector>
> > #include <iostream>

>
> > using namespace std;

>
> Don't put using directives in header files. Your decision to pull all
> identifiers from the standard namespace is inflicted upon every user of
> your class. That is very intrusive.
>
> > template <typename T> class myVector : public vector<T>
> > {
> > public:
> > void Sort();
> > };

>
> > template <typename T> void Sort<T>::Sort()

>
> Shouldn't that be something like
>
> template <typename T>
> void myVector::Sort()
>
> > {
> > if (this.size() < 2)
> > {
> > return;
> > }

>
> > vector<T>::iterator i;

>
> You would need to say
>
> typename std::vector<T>::iterator i;
>
> The keyword here is "dependent name".
>
>
>
> > for (i = this.begin(); i != this.end(); i++)
> > {
> > //rest part ignored....
> > }
> > }

>
> BTW: why are you doing your own sort algorithm? any why only for vectors? It
> is _very_ hard to beat std::sort() from the header <algorithm>.
>
> Best
>
> Kai-Uwe Bux



  Réponse avec citation
Vieux 18/10/2007, 10h47   #5
Kai-Uwe Bux
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to use the iterator from base class in a derived class?

wangxiaohu wrote:

> I just want to see if I can add a Sort() method to the existing vector
> container.
>
> What you've shown is write a individual function, which does work for
> the purpose, but does not answer my question.
>


It appears you asked out of curiosity. Here is one way to do it:

template < typename T >
class sort_vector : public std::vector< T > {
public:

sort_vector ( void )
: std::vector< T > ()
{}

template < typename A >
sort_vector ( A a )
: std::vector< T > ( a )
{}

template < typename A, typename B >
sort_vector ( A a, B b )
: std::vector< T > ( a, b )
{}

template < typename A, typename B, typename C >
sort_vector ( A a, B b, C c )
: std::vector< T > ( a, b, c )
{}

template < typename A, typename B, typename C, typename D >
sort_vector ( A a, B b, C c, D d )
: std::vector< T > ( a, b, c, d )
{}

void sort ( void ) {
std::sort( this->begin(), this->end() );
}

}; // sort_vector<>


Note the templated constructors. They just forward everything to the
underlying vector. One of those even allows to convert from std::vector<T>
to sort_vector<T>. That mitigates one of the most troublesome drawbacks of
public inheritance from standard containers: surprises when used with
functions like

template < typename T, typename A >
std::vector<T,A> reverse_order ( std::vector<T,A> const & );

Note that sort_vector<T> will match the argument type. But the result will
not be a sort_vector<T>.


> On 10 18 , 1 22 , Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>> wangxiaohu wrote:


and: please don't top post. It is frowned upon around these parts of the
net. See the FAQ for the sentiment about top-posting and other netiquette
matters that most regulars of this group share.


[snip]


Best

Kai-Uwe Bux
  Réponse avec citation
Vieux 20/10/2007, 21h58   #6
Tristan Wibberley
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Deriving from std containers (Was: How to use the iterator frombase class in a derived class?)


On Thu, 2007-10-18 at 08:04 +0000, Erik Wikström wrote:

> The general advice is to not inherit from the standard containers,
> instead create a class that wraps the container.


I'd heard that was because somebody might use a reference to your object
with type std::vector<...>& and use all the wrong functions. What about
private inheritance?

Is there any other problem that makes that a bad idea too?

It would save the repetitive typing of all the overloads to forward to
the implementation if one could just type "using std::vector<...>
member;" over and over with different members.

--
Tristan Wibberley

Any opinion expressed is mine (or else I'm playing devils advocate for
the sake of a good argument). My employer had nothing to do with this
communication.

  Réponse avec citation
Vieux 20/10/2007, 23h02   #7
Kira Yamato
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Deriving from std containers (Was: How to use the iterator from base class in a derived class?)

On 2007-10-20 16:58:47 -0400, Tristan Wibberley <maihem-nn1@maihem.org> said:

>
> On Thu, 2007-10-18 at 08:04 +0000, Erik Wikström wrote:
>
>> The general advice is to not inherit from the standard containers,
>> instead create a class that wraps the container.

>
> I'd heard that was because somebody might use a reference to your object
> with type std::vector<...>& and use all the wrong functions.


This doesn't make sense. I thought the whole point of Object-Oriented
Programming is that polymophisms are encouraged as a coding structure.

If a derived class can potentially ``damaged'' the integrity of the
base class, then as the designer of the base class he shouldn't have
allowed his methods be declared virtual (so that the derived class
could not override it). If so, how then can any reference of the base
class be using any wrong methods supplied by the derived class?

>
> Is there any other problem that makes that a bad idea too?


Yea, I like to know too.

--

-kira

  Réponse avec citation
Vieux 21/10/2007, 00h00   #8
Ian Collins
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Deriving from std containers (Was: How to use the iterator frombase class in a derived class?)

Tristan Wibberley wrote:
> On Thu, 2007-10-18 at 08:04 +0000, Erik Wikström wrote:
>
>> The general advice is to not inherit from the standard containers,
>> instead create a class that wraps the container.

>
> I'd heard that was because somebody might use a reference to your object
> with type std::vector<...>& and use all the wrong functions. What about
> private inheritance?
>
> Is there any other problem that makes that a bad idea too?
>

Standard containers don't have virtual destructors.

> It would save the repetitive typing of all the overloads to forward to
> the implementation if one could just type "using std::vector<...>
> member;" over and over with different members.
>


Rather than extending a container, consider providing a function or
operator that operates on one. std::sort would have solved the OP's
problem.

--
Ian Collins.
  Réponse avec citation
Vieux 21/10/2007, 00h25   #9
Tristan Wibberley
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Deriving from std containers (Was: How to use the iteratorfrom base class in a derived class?)


On Sat, 2007-10-20 at 18:02 -0400, Kira Yamato wrote:

> ... I thought the whole point of Object-Oriented
> Programming is that polymophisms are encouraged as a coding structure.


Standard containers are not object oriented then.

In the standard C++ library it's basically locale and iostreams related
stuff that is OO (or at least has OO aspects), the rest is just abstract
data types.

--
Tristan Wibberley

Any opinion expressed is mine (or else I'm playing devils advocate for
the sake of a good argument). My employer had nothing to do with this
communication.

  Réponse avec citation
Vieux 21/10/2007, 00h28   #10
Erik Wikström
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Deriving from std containers (Was: How to use the iterator frombase class in a derived class?)

On 2007-10-21 00:02, Kira Yamato wrote:
> On 2007-10-20 16:58:47 -0400, Tristan Wibberley <maihem-nn1@maihem.org> said:
>
>>
>> On Thu, 2007-10-18 at 08:04 +0000, Erik Wikström wrote:
>>
>>> The general advice is to not inherit from the standard containers,
>>> instead create a class that wraps the container.

>>
>> I'd heard that was because somebody might use a reference to your object
>> with type std::vector<...>& and use all the wrong functions.

>
> This doesn't make sense. I thought the whole point of Object-Oriented
> Programming is that polymophisms are encouraged as a coding structure.
>
> If a derived class can potentially ``damaged'' the integrity of the
> base class, then as the designer of the base class he shouldn't have
> allowed his methods be declared virtual (so that the derived class
> could not override it). If so, how then can any reference of the base
> class be using any wrong methods supplied by the derived class?


None of the standard library containers have any virtual functions, most
notably the destructor is not virtual. This is because they were not
designed to be inherited from.

>> Is there any other problem that makes that a bad idea too?

>
> Yea, I like to know too.


If the base class does not have a virtual destructor the derived class's
destructor will not be run when deleting a base class pointer pointing
to a derived object.

--
Erik Wikström
  Réponse avec citation
Vieux 21/10/2007, 00h28   #11
Tristan Wibberley
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Deriving from std containers


On Sun, 2007-10-21 at 12:00 +1300, Ian Collins wrote:
> Tristan Wibberley wrote:
> > On Thu, 2007-10-18 at 08:04 +0000, Erik Wikström wrote:
> >
> >> The general advice is to not inherit from the standard containers,
> >> instead create a class that wraps the container.

> >
> > I'd heard that was because somebody might use a reference to your object
> > with type std::vector<...>& and use all the wrong functions. What about
> > private inheritance?
> >
> > Is there any other problem that makes that a bad idea too?
> >

> Standard containers don't have virtual destructors.


That wouldn't be a concern with private inheritance since any pointer to
an instance of the container that might be "delete"ed *must* be
pointer-to-derived class and the correct destructor will be called -
unless the derived class exports a pointer to the base class (which
would be obviously problematic).

--
Tristan Wibberley

Any opinion expressed is mine (or else I'm playing devils advocate for
the sake of a good argument). My employer had nothing to do with this
communication.

  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 05h10.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,22595 seconds with 19 queries