IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Problème de classe abstraite


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 14
    Par défaut Problème de classe abstraite
    Bonjour à tous, je suis nouveau sur ce genre de forum d'habitude je me contente de lire pour résoudre mes problèmes mais cette fois je bloque .

    En gros je suis en train de faire un projet dans lequel je dois avoir une classe abstraite et deux classes filles( qui héritent donc de cette classe abstraite) , ce que j'ai fait dans un premier temps c'est définir les classes filles et maintenant que je dois tout lier ca ne marche pas du tout :/ (je me rend compte que j'aurai du faire l'inverse). Mon problème c'est que quand je fais l'héritage mon compilo me dit que la classe fille est abstraite et donc a chaque méthode ou j'ai en paramètre un objet de ma classe fille une erreur apparait (car on ne peut pas instancier des objets d'une classe abstraite). Auriez-vous une idée de ce que je fais mal ? Je pense que c'est mieux si vous voulez voir mon code de me le demander car ici ce serait trop long :/.

    Merci d'avance

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 14
    Par défaut Je suis sur une piste
    j'ai trouvé quelque chose, en testant une par une mes méthodes virtuelles pures, je suis tombé sur celles qui faisait faux bond.

    classe abstraite
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Min_Max{ //la classe de base
     
    public:
     
     
    	virtual void swap (Min_Max&  , Min_Max& ){} // si je met en pure ca va pas
    	virtual void swap (Min_Max& ){}
    	virtual bool empty() const = 0;
    	virtual std::size_t size () const = 0;
    	virtual std::size_t max_size() const = 0;
    	virtual bool operator==(const Min_Max& ){}
    	virtual bool operator!=(const Min_Max& ){}
    une des classes filles

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    class MinMax_Tab  : public Min_Max<T,sizemax>{
     
    private:
     
    	std::size_t _size = 0;
    	int Begin = 0;
    	int End = 0;
    	T *info = new T[sizemax+1];
     
     
    public:
     
    	void swap (MinMax_Tab& a , MinMax_Tab& b) //swap(a,b)
        	{
    			std::swap(a.Begin , b.Begin);
    			std::swap(a.End , b.End);
    			std::swap(a._size , b._size);
    			std::swap(a.info , b.info);
    		}
     
    	void swap (MinMax_Tab& b) //a.swap(b)
        	{
    		swap(*this,b);
    	}
     
     
     
     
    	bool operator==(const MinMax_Tab& rv) 
    	{
    		bool ok = 1;
    		if ( this->_size == rv._size)
    		{
    			tabconst_iterator i = rv.begin();
    			tabconst_iterator j = this->begin();
    			while ( i != rv.end() && j != this->begin() && ok == 1)
    			{
    				if (*i != *j)
    				{
    					ok = 0;
    				}
    				++i;
    				++j;
    			}
    		}
    		else
    		{
    			ok = 0;
    		}
    		return ok;
     
    	}
     
    	bool operator!=(const MinMax_Tab& rv) 
    	{
    		return !(*this==rv);
    	}
    en gros ca me dit que l'objet de MinMax_tab que je crée est impossible a créer car MinMax_Tab est une classe abstraite, par contre si j'enleve le = 0 apres la définition de swap et des opérateurs dans le code de la classe mère, tout compile parfait , j'ai l'impression que c'est parce que je n'ai pas les mêmes types de données en parametre donc il compte ca comme de l'overloading et pas de l'overriding, ca m'embête :/

    PS ici le code de mes méthodes n'est pas forcément important c'est surtout les déclarations qui sont importantes.

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    En gros, il faut savoir un truc: le compilateur a horreur du vide...

    Si tu déclares une fonction virtuelle comme étant pure ( == sans implémentation) dans la classe mère, le compilateur saura qu'elle existe, ce qui est déjà pas mal mais, si tu ne fournis pas une implémentation pour cette fonction dans les classes qui en dérivent, ben... le compilateur ne saura pas fournir lui-même l'implémentation de cette fonction.

    Et, du coup, la fonction sera considérée comme... virtuelle pure dans la classe dérivée.

    Et comme le compilateur a horreur du vide et que ca ferait vraiment désordre s'il permettait la création d'une instance de classe abstraite, mais que, du fait de la fonction virtuelle pure, la classe dérivée est aussi considérée comme abstraite, le compilateur n'a pas d'autre choix que de t'engueuler parce que tu essaye d'instancier une classe abstraite en créant une instance de la classe dérivée.

    C'est aussi simple que cela

    La solution, elle est toute simple: toutes les fonctions virtuelles pures de ta classe de base doivent être implémentées au niveau des classes dérivées concrètes.

    Ceci étant dit, j'aimerais comprendre comment tu passe d'une classe non template (avec des fonctions virtuelles pures) Min_Max un héritage où la classe mère est une classe template Min_Max<T,sizemax>, car l'un dans l'autre, il y a une des classes (à vue de nez, j'aurais même tendance à dire deux: la classe mère non template et la classe la MinMax_Tab) qui est totalement inutile
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 14
    Par défaut j'ai juste mal copié pour la classe fille
    pour la classe fille le template est une ligne plus haut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     <typename T, std::size_t sizemax>
    ce que je ne comprends pas c'est pourquoi le compilo ne prend pas mon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void swap (MinMax_Tab& a , MinMax_Tab& b)
    pour mon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual void swap (Min_Max&  , Min_Max& )
    je veux dire MinMax_Tab hérite de Min_Max donc tout les objets MinMax_Tab sont aussi de objets de Min_Max...

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Citation Envoyé par Shpounz Voir le message
    pour la classe fille le template est une ligne plus haut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     <typename T, std::size_t sizemax>
    N'hésite pas à éditer ton message.

    Citation Envoyé par Shpounz Voir le message
    je veux dire MinMax_Tab hérite de Min_Max donc tout les objets MinMax_Tab sont aussi de objets de Min_Max...
    Ceci est vrai lorsque tu appelles un fonction, c'est le Principe de Substitution de Liskov.

    Mais ici, tu redéfinis ta fonction membre virtuelle dans la classe dérivée.
    Citation Envoyé par Shpounz Voir le message
    ce que je ne comprends pas c'est pourquoi le compilo ne prend pas mon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void swap (MinMax_Tab& a , MinMax_Tab& b)
    pour mon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual void swap (Min_Max&  , Min_Max& )
    Et pour ce faire, tu dois avoir exactement la même signature, sinon tu ne redéfinis pas la fonction, mais la masques. Le mot-clé override est justement là pour éviter ce problème.
    Ceci à une exception près : le type de retour covariant qui tire justement parti de l'héritage, mais il n'est possible que sur le type de retour de la fonction et PAS ses entrées.

    • Intéresse-toi au CRTP.
    • Qualifie tes operator d'(in)égalité de const : ils ne modifient pas l'instance.
    • T *info = new T[sizemax+1]; : utilise std::vector à la place.
    Dernière modification par Invité ; 14/08/2022 à 02h57.

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2017
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2017
    Messages : 14
    Par défaut Merci de votre réponse
    si je comprends bien, MinMax_Circ n'est pas un Min_Max ( je ne respecte pas le principe de substitution) mais je ne vois pas en quoi ce n'est pas un bon héritage, j'ai essayé les masques ca ne me permet toujours pas d'override par contre mais certain warnings disparaissent ("was hiden ..."). Quand je met le mot clef override apres mes méthodes swap et mes redefinitions d'opérateurs == et != le compilateur me met un message d'erreur comme quoi je n'override rien du tout. C'est a s'y prendre la tête je pensais pourtant faire ce qu'il y a de plus simple en terme d'héritage si j'hérite de Min_Max les objets de la classe dont j'herite sont aussi des objets de type Min_Max ... appraement pas

    Merci en tout cas de vous donner le mal de m'expliquer

    Ah et pour std::vector l'énoncé impose que je laisse l'array sous cette forme

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 26/08/2011, 13h44
  2. Problème avec classe abstraite
    Par Antoniom dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 29/01/2011, 13h03
  3. Problème héritage et classes abstraites
    Par sebzinzin dans le forum Langage
    Réponses: 4
    Dernier message: 03/06/2007, 18h24
  4. [Classe abstraite] Problème de surcharge
    Par Bleys dans le forum Langage
    Réponses: 8
    Dernier message: 26/04/2007, 11h44
  5. Problème de dérivation d'un class abstraite
    Par the big ben 5 dans le forum Delphi .NET
    Réponses: 8
    Dernier message: 20/07/2006, 20h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo