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

C++ Discussion :

passage de collection heterogene en parametre


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2016
    Messages : 6
    Par défaut passage de collection heterogene en parametre
    Bonjour,

    Je développe un jeu en C++ sous Windows avec Codeblocks et avec SFML.
    Comme le titre l'indique je tente de passer une collection hétérogène , (un vector de pointeurs sur Vaisseau) , à une méthode qui reçoit comme paramètre un vector de pointeur sur Objet.

    Tout cela sachant que Vaisseau Hérite d'une classe qui hérite d'Objet.


    voici la méthode appelée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    bool Objet::collision(vector< Objet*>& listeObjetsDistants )
    {
    ...
    }
    et voici l'appel de celle ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    m_listeVaisseau[i]->collision(m_listeVaisseau);
    sachant que m_listeVaisseau est déclarée comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::vector<Vaisseau*> m_listeVaisseau;
    Je sais qu'en java il faut résoudre ce problème avec l’implémentation d'une methode générique qui reçoit n'importe quel sous-type de Objet*.

    Mais en C++, je ne connais pas d'équivalent, et j'aimerai bien éviter le plus possible de devoir caster tout le vector car la complexité algorithmique ralentirait beaucoup le jeu.

  2. #2
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Bonjour

    Tu peux utiliser des templates comme dans cette exemple en C++14 :
    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
    // g++ -Wall -Wextra -Wconversion -Wsign-conversion -Ofast -std=c++14 -pedantic -fopenmp main.cpp -o main && ./main
    // g++ -Wall -Wextra -Wconversion -Wsign-conversion -Og -ggdb3 -std=c++14 -pedantic main.cpp -o main && valgrind ./main
     
    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include <limits>
    #include <type_traits>
    #include <memory>
     
     
    class base
    { };
     
    class derived : public base
    { };
     
    template <class T>
    void fct1(std::vector<T> const & v)
    {
    	for (auto const & e : v) { std::cout << "fct1" << std::endl; }
    }
     
    template <class T>
    void fct2(T const & v)
    {
    	for (auto const & e : v) { std::cout << "fct2" << std::endl; }
    }
     
    int main()
    {
    	std::cout << "std::vector<derived>" << std::endl;
    	std::cout << std::endl;
    	{
    		std::vector<derived> v = { derived(), derived(), derived() };
     
    		fct1(v); std::cout << std::endl;
    		fct2(v); std::cout << std::endl;
    	}
     
     
    	std::cout << "std::vector<std::unique_ptr<derived>>" << std::endl;
    	std::cout << std::endl;
    	{
    		std::vector<std::unique_ptr<derived>> v;
    		v.push_back(std::make_unique<derived>());
    		v.push_back(std::make_unique<derived>());
     
    		fct1(v); std::cout << std::endl;
    		fct2(v); std::cout << std::endl;
    	}
     
    	return 0;
    }
    Quelques remarques :

    La différence entre les fonctions fct1 et fct2 est au niveau de son paramètre. fct1 prend un std::vector contenant n'importe quel élément (mais de même type statique) alors que fct2 prend n'importe quel type. Dans les templates, c'est l'utilisation des paramètres qui fait que la fonction template peut être générée ou pas. Du coup, fct2 fonctionne aussi avec une std::list (contrairement à fct1).

    Si tu n'as pas "besoin de l'héritage" dans le sens où tu n'as pas besoin d'avoir le comportement polymorphique du typage dynamique, tu peux utiliser directement utiliser un std::vector<derived>. C'est plus simple et globalement plus rapide.

    Si tu as "besoin de l'héritage", utilise std::unique_ptr. Il gère la mémoire pour toi, pas besoin de new (grâce à std::make_unique) ni de delete.

  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,

    Bon, avant de commencer, j'aurais deux remarques à faire concernant l'utilisation d'un :

    La première, c'est que tu devrais utiliser des pointeurs intelligents pour gérer la durée de vie de tes objets. Ainsi, si ton tableau est propriétaire des éléments qu'il contient (comprend : si le tableau doit détruire les objets qu'il contient lorsque ceux-ci sont retirés du tableau), tu devrais sans doute te tourner vers un std::vector<std::unique_ptr>> afin d'éviter tout risque de fuite mémoire

    La deuxième est que le terme Object a le don de me faire tiquer dés que je le rencontre dans un code : la notion même d'un objet est, par définition même, beaucoup trop imprécise pour pouvoir en faire quelque chose d'efficace en respectant le LSP (Liskov Substitution Principle ou principe de substitution de Liskov).

    En effet, la définition du terme objet, tel que l'on pourrait la trouver dans un dictionnaire est très proche de
    un élément que l'on peut utiliser à sa guise
    Alors, oui : partant de ce genre de définition, il nous serait très (beaucoup trop, à vrai dire) facile d'estimer que "tout est object".

    Sauf que, pour que cela ait du sens de partir sur une idée de ce genre, il faudrait que notre classe Object puisse exposer tous les comportements polymorphes dont nous sommes susceptibles d'avoir besoin au niveau... de toutes les classes qui dériveraient de la classe Object.

    Et là, nous allons aller vers un problème, car le LSP nous dit que toute propriété valide pour le type de base doit être valide pour le type dérivé. Si bien que si l'on considère le fait qu'un vaisseau doit proposer une propriété que nous pourrions définir sous la forme de
    expose une fonction déplace toi (vers telle position / de telle distance sur les différents axes)
    nous allons "naturellement" être menés à estimer que cette propriété doit aussi être exposée par la classe Object, afin de pouvoir utiliser les éléments "connus comme étant des objets" sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ptrObject->moveTo(position);
    Seulement, ce serait aussi oublier un peu vite que, si "tout peut être Object", une classe Wall (par exemple) a de grandes chances d'hériter elle aussi de la classe Object... Or, un mur n'est certainement pas quelque chose qui est susceptible d'être déplacé . On ne peut donc décemment pas estimer que la propriété "expose une fonction moveTo (ou move, ou toute fonction impliquant le déplacement de l'objet)", qui serait considérée comme "valide pour le type de base" (pour la classe Object) est effectivement une propriété valide pour le type dérivé (notre éventuelle classe Wall); ce qui irait à l'encontre du LSP, et qui représente donc un NO-GO impératif du point de vue conceptuel.

    Ceci étant dit, si tu veux profiter du polymorphisme d'inclusion, la méthode est toute simple : tu déclares une fonction virtuelle (qui pourrait être virtuelle pure) dans la classe de base, et tu veille à fournir une implémentation de cette fonction dans chaque classe pour laquelle il devient possible de définir un comportement particulier.

    Et, dans le pire des cas, si tu as "été assez bête" pour "perdre le type réel" d'un objet donné (parce que tu ne le connait que comme "étant du type de base"), tu pourras toujours recourir au double dispatch si tu respecte correctement le DIP (Dependancies Inversion Principle ou principe d'inversion des dépéendances) et dont un exemple "classique" est fourni au travers du patron de conception visiteur.

    Ouff... voilà qui fait beaucoup de liens... Je vais donc te laisser intégrer toutes ces remarques et tous ces renseignements, en espérant qu'ils te permettent de te "sortir d'affaire".

    Mais n'hésite pas à demander plus de précisions en cas de besoin
    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 régulier
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2016
    Messages : 6
    Par défaut reponse
    merci Ehonn,

    j'ai implémenté ta solution template pour pouvoir continuer à compiler et tester les multiples modifications du projet qui étaient en cours et ne pas les perdre.
    Malgré cela, je trouve que C++ est vraiment archaïque sur ce plan car ça contredis completement le modèle objet:

    En effet, je n'ai plus le comportement associé a la liaison dynamique, car ma méthode collision est devenue template et donc elle ne peut plus être virtual ,or si j'ai pensé toute cette hiérarchie de classe c'est justement pour cela.

    Pour ce qui est de la conception:
    • Objet n'est qu'un nom de classe temporaire en attendant de résoudre les problèmes les plus importants sachant que mon équipe et moi découvrons l'usage avancé du C++ et avons un tas d'autres problèmes a résoudre au niveau de l'architecture logicielle etc.. (une chose a la fois)
    • Cette classe Objet rassemble le code sur la physique, elle se nommera probablement très bientôt "PhysicObject", a vrai dire je ne pense pas à ça pour le moment (tant que nous avons la sémantique en tete , un demi dizaine de "Rechercher-Remplacer" fera l'affaire par la suite).
    • Pareil pour les pointeurs uniques , automatiques , magiques ou méme féeriques... si je peux résoudre mon problème je passerai ensuite a l'optimisation.
    • Le LSP est respecté et la conception de la hiérarchie de classe a été volontairement simplifiée pour respecter les consignes qui sont de soumettre une question claire, précise.
    • Je ne connaissait pas le principe d'inversion des dépendances, c'est très intéressant car je suis passionné par le C++, mais ça ne m'aide pas dans le cas présent, mais je sais que tu n'est "pas si bete que tu n'en a l'air" donc tu dois probablement déjà le savoir .
    • J'aurai préféré ouvrir un autre sujet pour discuter de la conception.

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par défaut
    Citation Envoyé par jordanferrad Voir le message
    merci Ehonn,

    j'ai implémenté ta solution template pour pouvoir continuer à compiler et tester les multiples modifications du projet qui étaient en cours et ne pas les perdre.
    Malgré cela, je trouve que C++ est vraiment archaïque sur ce plan car ça contredis completement le modèle objet:

    En effet, je n'ai plus le comportement associé a la liaison dynamique, car ma méthode collision est devenue template et donc elle ne peut plus être virtual ,or si j'ai pensé toute cette hiérarchie de classe c'est justement pour cela.
    Je suis très mitiger sur l'utilisation d'une hiérarchie de classe pour une fonction collision. Généralement, pour appliquer la formule appropriée, il faut connaitre la forme réel de objet et donc adieu polymorphisme, bonjour solution à base de visiteur (ou double dispatch) comme indiqué par koala01.

    Cela dit, si tu tiens absolument à un tableau d'objet en paramètre, plusieurs solutions existent:

    • Comme le dit Ehonn, ne pas utiliser vector<Vaisseau>, mais que vectors<Objet>. Ou faire un wrapper qui publiquement donne l’impression de manipuler un vector de Vaisseau, mais en interne manipule un vector d'Objet. Avec des statique_cast partout mais cela se justifie. (Pour le coup, la surcharge de l'operator. serait vachement pratique pour ne pas se taper la réécriture de l'interface de vector.)
    • Utiliser un type moins restreint comme un array_view qui possède un constructeur pouvant prendre un "conteneur" et extrait les infos avec cont.data() et cont.size(). Les prototypes des fonctions changent, mais la conversion d'un vector<Vaisseau> en array_view<Objet> est transparente. Par contre, la vue n'a pas la main sur le vector, donc pas d'ajout ou de suppression d'élément. La modification reste toutefois possible.
    • Faire un cast () car, finalement, les types ont une représentation compatible.

  6. #6
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Citation Envoyé par jordanferrad Voir le message
    • Pareil pour les pointeurs uniques , automatiques , magiques ou méme féeriques... si je peux résoudre mon problème je passerai ensuite a l'optimisation.
    Il ne s'agit pas d'optimisation.

    Une fois maîtrisé, utiliser un std::unique_ptr à la place d'un pointeur sur lequel il faudrait faire un delete a de gros avantages :
    -Cela indique de manière très explicite qui est responsable de libérer la ressource.
    -Cela permet d'écrire facilement du code sans fuite mémoire.
    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
    // Code sans fuite mémoire, mais lourd :
    {
    	std::vector<Toto*> v;
    	try {
    		v.push_back(new Toto());             // peut lever une exception
    		v.push_back(new Toto());             // peut lever une exception
    		fonctionQuiPeutLeverUneException(v); // peut lever une exception
    	} catch(...) {
    		for(Toto* toto : v)
    			delete toto;
    		throw;
    	}
    	for(Toto* toto : v)
    		delete toto;
    }
    // Code sans fuite mémoire, et simple :
    {
    	std::vector<std::unique_ptr<Toto>> v;
    	v.push_back(std::make_unique<Toto>()); // peut lever une exception
    	v.push_back(std::make_unique<Toto>()); // peut lever une exception
    	fonctionQuiPeutLeverUneException(v);   // peut lever une exception
    } // La mémoire est toujours libérée.
    Le seul vrai inconvénient, c'est que ça demande un temps d'apprentissage. En particulier, il est préférable d'apprendre, au préalable, la notion de rvalue reference.

    Citation Envoyé par jordanferrad Voir le message
    Pour les références constantes etc je me casse pas la tete pour le moment je veux juste un truc qui marche et j'optimise tout après.
    Les const ont plusieurs avantages, dont les suivants :
    -Ils apportent une information sémantique à l'utilisateur : une fonction qui a pour paramètre une référence constante ne modifiera pas l'objet en paramètre.
    -Ils sont contrôlés à la compilation.

    Le problème avec les const, c'est que c'est plus difficile à introduire a posteriori que dès le départ.
    Par exemple, admettons que tu aies :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    std::string toStdString(Personne* personne)
    {
    	if(personne)
    		return getPrenomEtNom(*personne);
    	else
    		return std::string();
    }
    Plus tard, tu décides de t'attaquer aux const et tu fais un passage par pointeur vers objet constant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::string toStdString(const Personne* personne)
    Et là, VLAN, le compilateur affiche une erreur, parce que getPrenomEtNom prend en paramètre une référence non constante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::string getPrenomEtNom(Personne& personne)
    {
    	return personne.getPrenom() + " " + personne.getNom();
    }
    Alors, tu corriges :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::string getPrenomEtNom(const Personne& personne)
    Et là, re-VLAN, le compilateur affiche une erreur, parce que les fonctions Personne::getPrenom() et Personne::getNom() n'ont pas encore été déclarées constantes.

    Sur un exemple plus compliqué, cela peut continuer encore longtemps avant que ça compile.
    Par contre, quand on met des const dès le départ, on évite ce genre de soucis.

  7. #7
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Bonjour.

    Citation Envoyé par jordanferrad Voir le message
    Comme le titre l'indique je tente de passer une collection hétérogène , (un vector de pointeurs sur Vaisseau) , à une méthode qui reçoit comme paramètre un vector de pointeur sur Objet.

    Tout cela sachant que Vaisseau Hérite d'une classe qui hérite d'Objet.


    voici la méthode appelée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    bool Objet::collision(vector< Objet*>& listeObjetsDistants )
    {
    ...
    }
    [...]

    Mais en C++, je ne connais pas d'équivalent, et j'aimerai bien éviter le plus possible de devoir caster tout le vector car la complexité algorithmique ralentirait beaucoup le jeu.
    Je remarque que ton paramètre listeObjetsDistants est une référence non constante.

    Selon le LSP, une collection de Vaisseaux ne peut pas être considérée comme un sous-type d'une collection non constante d'Objets.
    La raison est que, dans une collection non constante d'Objets, on peut ajouter n'importe quel Objet, même de type autre que Vaisseau, alors que ce n'est pas le cas dans une collection de Vaisseaux.

    Par contre, on peut considérer une collection de Vaisseaux comme un sous-type d'une collection constante d'Objets.
    Pour implémenter cela en C++ de manière orientée objet, on peut créer une classe de base CollectionConstanteObjets qui aurait deux classes dérivées CollectionObjets et CollectionVaisseaux.
    Mais cela impliquerait d'écrire plus de code que la solution où la classe Objet aurait un modèle de fonction membre :
    template<class T> bool collision(const std::vector<T*>& listeObjetsDistants)

    Remarque : C'est analogue au problème Cercle-Ellipse :
    Un cercle peut être considéré comme un sous-type d'une ellipse constante, mais pas comme un sous-type d'une ellipse non constante, sauf si on "triche".

    Citation Envoyé par jordanferrad Voir le message
    En effet, je n'ai plus le comportement associé a la liaison dynamique, car ma méthode collision est devenue template et donc elle ne peut plus être virtual ,or si j'ai pensé toute cette hiérarchie de classe c'est justement pour cela.
    Pourquoi veux-tu que cette fonction collision, qui prend en paramètre une collection, soit virtuelle ?

    Pour ton besoin, n'est-t-il pas suffisant d'avoir une fonction collision non virtuelle qui prend en paramètre une collection et qui, pour chaque élément de cette collection, appelle une autre fonction collision, qui elle est virtuelle ?

  8. #8
    Membre régulier
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Avril 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2016
    Messages : 6
    Par défaut
    Bonjour,

    Pourquoi veux-tu que cette fonction collision, qui prend en paramètre une collection, soit virtuelle ?
    En fait je pose un modèle général et je ne sais pas encore de quoi j'aurai besoin plus tard et si dans une des sous classe j'ai besoin de redéfinir la methode collision;
    à l'éxécution sera appelée la methode collision la plus spésialisée ( s 'il s'agit d'un classe derivée je ne sait pas encore combien de fois), ou en l'absence de redéfinition , de la première implémentée dans la classe Objet.

    Pour les références constantes etc je me casse pas la tete pour le moment je veux juste un truc qui marche et j'optimise tout après.

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    En l'occurence les paramètres par const& sont le B.A.BA de la bonne pratique, l'optimisation facile et fonctionne partout.
    A l'inverse de la référence non-const.

    Sinon, moi ce qui me chagrine c'est : pourquoi vouloir le faire en C++ si vous avez des compétences en JAVA ?

    Et pour ce que je comprends du problème, une fonction qui prend un vector d'objet pour une collision, ça me parait au mieux overkill. C'est Objet qui doit tester sa collision avec un autre Objet, et lui qui possède une implémentation virtuelle de Collide(const Object& other), que l'on pourra spécialiser pour les différents sous-objets si nécessaire, et où l'utilisation du double-dispatch est des plus communes.

    En fait je pose un modèle général et je ne sais pas encore de quoi j'aurai besoin plus tard et si dans une des sous classe j'ai besoin de redéfinir la methode collision;
    Ceci est le meilleur moyen amha d'over-engineerer un système qui au final sera simple parce que de telles redéfinitions s'avèrent souvent inutiles à la fin, de perdre du temps sur de la broutille et pas assez sur d'autres aspects plus importants comme faire le jeu.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  10. #10
    Membre éclairé
    Homme Profil pro
    Cocher moderne
    Inscrit en
    Septembre 2006
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Oman

    Informations professionnelles :
    Activité : Cocher moderne

    Informations forums :
    Inscription : Septembre 2006
    Messages : 50
    Par défaut
    Citation Envoyé par jordanferrad Voir le message
    Pour les références constantes etc je me casse pas la tete pour le moment je veux juste un truc qui marche et j'optimise tout après.
    Je rebondis juste sur cette remarque, de la manière la plus positive possible!

    À mon sens, en C++, on ne peut pas plus se passer du LSP en programmation objet que de la const-correctness. Et on ne peut pas appeler ça de "l'optimisation".

    J'ai envie d'aller plus loin: la const-correctness permet de mettre en lumière rapidement et sans doute aucun les architectures bancales! Lorsqu'on débute dans son coin, il est effectivement très frustrant de se faire envoyer sur les roses par le compilateur qui vous explique de manière pas toujours très claire que vous essayez de modifier un invariant.

    Néanmoins, - et il faut s'en persuader, pas toujours facile quand on débute! - c'est une aide énorme, surtout lorsqu'on "se jette dans le code" sans toujours avoir une idée bien précise de comment tout ça va s'articuler.

    Et je pense que c'est le cas ici.

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

Discussions similaires

  1. Passage d'un pointeur en parametre
    Par vandamme dans le forum C++
    Réponses: 3
    Dernier message: 15/06/2008, 22h10
  2. passage d'un vecteur en parametre
    Par Master C dans le forum Débuter
    Réponses: 2
    Dernier message: 19/02/2008, 20h39
  3. passage d'un tableau en parametre d'une fonction
    Par ataya dans le forum C++Builder
    Réponses: 10
    Dernier message: 26/10/2005, 13h30
  4. [POO] passage nom objet dsn les parametres d'une fonction
    Par melou dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 21/10/2005, 17h26
  5. passage d'une variable en parametre
    Par duga dans le forum Langage
    Réponses: 4
    Dernier message: 11/09/2005, 12h19

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