2009-10-14 8 views
2

Je crée une nouvelle classe qui hérite de la file d'attente de la bibliothèque STL. Le seul ajout à la classe est un vecteur. Ce vecteur aura la même taille de la file d'attente et il stockera des valeurs entières qui correspondront à chaque objet de la file d'attente.C++ Appel de méthode de classe parent

Maintenant, je veux remplacer pop() et push(), mais je veux simplement ajouter plus de fonctionnalités aux méthodes de classe du parent.

ex. Quand pop() est appelé sur l'objet queue, je veux aussi faire apparaître un objet du vecteur. Quand push() est appelé sur l'objet queue, je veux aussi insérer un nouvel objet dans le vecteur.

Comment je fais ça ???

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

using namespace std; 

template <typename type> 
class CPU_Q : public queue<type> 
{ 

    public: 
    vector<int> CPU_TIME; 

    void increaseTime() 
    { 
     for(int ndx = 0; ndx < CPU_TIME.size(); ndx++) 
     { 
     CPU_TIME[ndx]++; 
     } 
    } 

    void push(type insertMe) 
    { 
    //This is what I want to do 
    super::push(); // or queue::push(); maybe? 
    CPU_TIME.push_back(0); 
    } 
    void pop() 
    { 
    //Something very similar to push() 
    } 
} 

Un grand merci à l'avance

-Tri

+1

La raison de C++ ne pas avoir un mot-clé 'super' est probablement en C++ il y a l'héritage multiple.Vous pouvez avoir plusieurs classes de base/super. Donc, vous utilisez le type correct de la classe de base à la place: 'queue :: push (insertMe)'. Cependant, assurez-vous de lire les réponses expliquant pourquoi l'héritage des conteneurs STL ne correspond probablement pas à ce que vous voulez. – sbi

+0

Avez-vous également considéré simple de mettre ces valeurs dans une structure de leur propre, de sorte que vous pouvez toujours garantir que les valeurs connexes sont ajoutées et supprimées ensemble? – UncleBens

Répondre

6

méthode de classe de base Vous avez demandé:

void push(type insertMe){ 
     //This is what I want to do 
     super::push(); // or queue::push(); maybe? 
     CPU_TIME.push_back(0); 
} 

Ce serait plus comme:

void push(type insertMe) { 
    queue<type>::push(insertMe); 
    CPU_TIME.push_back(0); 
} 

Sauf que vous voulez probablement accepter le paramètre par référence const:

void push(type const &insertme) { 
    queue<type>::push(insertMe); 
    CPU_TIME.push_back(0); 
} 

Cela dit, les classes de conteneur standard ne sont pas lly conçu pour l'héritage (par ex. ils n'ont pas d'agents virtuels), vous devrez donc faire attention à cela - par ex. lorsque vous le détruisez, vous aurez besoin du type statique pour être le type dérivé; vous obtiendrez un comportement indéfini si (par exemple) vous détruisez un via un pointeur vers la classe de base.

+0

Dites-vous que dériver de la file d'attente est valide? – Ponting

+1

Avec un soin suffisant, oui. Je ne suis pas sûr que je le recommanderais vraiment, mais il n'y a rien qui le rend automatiquement invalide. –

+1

Dériver de la file d'attente est certainement * non * valide, mais ce n'est pas "non possible" non plus. Je recommande de conserver la file d'attente en tant que variable d'instance et de transférer tous les appels push()/pop(). –

1

réponse simple est qu'il est impossible. Les classes de conteneur STL ne sont pas conçues pour être héritées. Leur destructeur n'est pas virtuel pour commencer. Si vous voulez vraiment faire quelque chose comme ça, alors écrivez une nouvelle classe qui "contient" la file d'attente et le vecteur, et utilisez cette classe partout. BTW comme une note latérale, il n'y a pas de mot-clé super en C++ contrairement à Java. Si vous voulez appeler utiliser BaseClassName::methodName();

+1

Eh bien, c'est possible. Ce qui est impossible, c'est de traiter la classe résultante comme une 'std :: queue '. Classic _polymorphism_ ne fonctionne pas avec le STL. (Le polymorphisme à la compilation le fait cependant.) – sbi

+0

Oui ... ce que je voulais dire, c'est que vous ne pouvez pas réacheminer les appels aux méthodes pop() etc de file d'attente en utilisant la liaison dynamique. – Ponting

+0

Je ne comprends pas les derniers downvotes..il y a quelque chose de mal dans la réponse? – Ponting

1

À moins que votre nouvelle classe a une est-une relation avec std::queue, je voudrais envisager l'encapsulation de la file d'attente et le vecteur, et en fournissant des méthodes avant les méthodes std::queue/std::vector appropriées, dans l'ordre que vous voulez qu'ils soient appelé.

En outre, si vous voulez que cette nouvelle classe pour être compatible avec les algorithmes standard, vous devrez mettre en œuvre une méthode begin() et end() qui renvoient un capable de marcher votre structure de données de type iterator; vous pouvez peut-être utiliser les méthodes existantes sur std::queue/std::vector pour ce faire.

2

La classe de file d'attente STL n'est pas destinée à être étendue en utilisant l'héritage. Regardez here pour plus d'informations à ce sujet. En outre, std::queue a plus d'un argument de modèle. Au lieu de vous héritant pouvez simplement utiliser std::queue comme membre de votre classe de modèle CPU_Q comme suit:

template<typename T> 
class CPU_Q 
{ 
    std::queue<T> q; 
public: 
    void push(T val) 
    { 
    q.push(val); 
    // additional work 
    } 
}; 
+1

C'est le confinement au lieu de l'héritage, ce qui pourrait être mieux, mais aurait probablement besoin d'explications pour être compris. – sbi

+0

Remarque: 'queue' et' stack' ont un membre protégé. Cela implique qu'il y a une circonstance que l'héritage a du sens. Cependant, je serais encore d'accord que la composition est préférée. –

Questions connexes