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 :

Héritage, destructeurs et performances


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut Héritage, destructeurs et performances
    Bonsoir,

    je constate une nette perte de performances selon la manière dont je définis le destructeurs de mes classes de base et je ne comprends pas pourquoi.

    J'ai une classe de base Number,

    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
     
    #ifndef _NUMBER_HPP
    #define	_NUMBER_HPP
    /*! 
     * \class Number
     * \brief This is the base class for all real numbers (including integers).
     * \warning This class is not abstract so as to maintain good performance.
     */
    class Number
    {
    protected:
        /*!
         * \fn Number()
         * \brief default constructor
         * \warning this constructor MUST NOT be public
         */
        Number(){;};
    };
    ////////////////////////////////////////////////////////////////////////////////
    #endif	/* _NUMBER_HPP */
    dont hérite une classe générique Real<T> (à terminer) :
    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
     
    #ifndef _REAL_HPP
    #define	_REAL_HPP
    #include "Number.hpp"
    /*! 
     * \class Real
     */
    template<typename T>
    class Real : public Number
    {
    protected:
        /*! \brief value of the real number */
        T _value;
    protected:
        /*! \brief default construction */
        Real();
        /*! \brief copy construction */
        Real(T const&);
    public:
        /*! \brief assignement of a real number */
        T const& operator=(T const&);
        /*! \brief computation of the absolute value */
        double abs()const;
    public:
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator==(Real<TT>const&,Real<TT>const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator==(TT const&,Real<TT>const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator==(Real<TT>const&,TT const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator<=(Real<TT>const&,Real<TT>const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator<=(TT const&,Real<TT>const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator<=(Real<TT>const&,TT const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator>=(Real<TT>const&,Real<TT>const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator>=(TT const&,Real<TT>const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator>=(Real<TT>const&,TT const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator<(Real<TT>const&,Real<TT>const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator<(TT const&,Real<TT>const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator<(Real<TT>const&,TT const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator>(Real<TT>const&,Real<TT>const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator>(TT const&,Real<TT>const&);
        /*! \brief comparison of two real numbers */
        template<typename TT>
        friend bool operator>(Real<TT>const&,TT const&);
    public:
        /*! \brief addition of two real numbers */
        template<typename TT>
        friend TT operator+(Real<TT>const&,Real<TT>const&);
        /*! \brief addition of two real numbers */
        template<typename TT>
        friend TT operator+(Real<TT>const&,TT const&);
        /*! \brief addition of two real numbers */
        template<typename TT>
        friend TT operator+(TT const&,Real<TT>const&);
        /*! \brief substraction of two real numbers */
        template<typename TT>
        friend TT operator-(Real<TT>const&,Real<TT>const&);
        /*! \brief substraction of two real numbers */
        template<typename TT>
        friend TT operator-(Real<TT>const&,TT const&);
        /*! \brief substraction of two real numbers */
        template<typename TT>
        friend TT operator-(TT const&,Real<TT>const&);
        /*! \brief multiplication of two real numbers */
        template<typename TT>
        friend TT operator*(Real<TT>const&,Real<TT>const&);
        /*! \brief multiplication of two real numbers */
        template<typename TT>
        friend TT operator*(TT const&,Real<TT>const&);
        /*! \brief multiplication of two real numbers */
        template<typename TT>
        friend TT operator*(Real<TT>const&,TT const&);
        /*! \brief division of two real numbers */
        template<typename TT>
        friend TT operator/(Real<TT>const&,Real<TT>const&);
        /*! \brief division of two real numbers */
        template<typename TT>
        friend TT operator/(TT const&,Real<TT>const&);
        /*! \brief division of two real numbers */
        template<typename TT>
        friend TT operator/(Real<TT>const&,TT const&);
    };
    ////////////////////////////////////////////////////////////////////////////////
    #include "Real.tcc"
    #endif	/* _REAL_HPP */
    Cette dernière classe sert à représenter les nombres réels (float,double,int,...) et utilise des méthodes en ligne pour rester proches des performances initiales des opérations élémentaires (+,-,*,/,...) sur les types numériques (float,double,int) :
    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
     
    #ifndef _REAL_TCC
    #define	_REAL_TCC
    template<typename T>
    inline Real<T>::Real()
    {}
    /*!
     * \fn Real(T const&)
     * \param value of a real number
     * \brief construction by value
     */
    template<typename T>
    inline Real<T>::Real(T const& value)
    :Number(),_value(value)
    {}
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \fn inline T& operator=(T const&)
     * \param value of a real number
     * \brief assignement of a value
     */
    template<typename T>
    inline T const& Real<T>::operator=(T const& value)
    {
        return _value=value;
    }
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \param left operand
     * \param right operand
     * \brief addition of two real numbers
     */
    template<typename TT>
    inline TT operator+(Real<TT>const& left,Real<TT>const& right)
    {
        return left._value+right._value;
    }
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \param left operand
     * \param right operand
     * \brief addition of two real numbers
     */
    template<typename TT>
    inline TT operator+(Real<TT>const& left,TT const& right)
    {
        return left._value+right;
    }
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \param left operand
     * \param right operand
     * \brief addition of two real numbers
     */
    template<typename TT>
    inline TT operator+(TT const& left,Real<TT>const& right)
    {
        return left+right._value;
    }
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \param left operand
     * \param right operand
     * \brief substraction of two real numbers
     */
    template<typename TT>
    inline TT operator-(Real<TT>const& left,Real<TT>const& right)
    {
        return left._value-right._value;
    }
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \param left operand
     * \param right operand
     * \brief substraction of two real numbers
     */
    template<typename TT>
    inline TT operator-(Real<TT>const& left,TT const& right)
    {
        return left._value-right;
    }
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \param left operand
     * \param right operand
     * \brief substraction of two real numbers
     */
    template<typename TT>
    inline TT operator-(TT const& left,Real<TT>const& right)
    {
        return left-right._value;
    }
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \param left operand
     * \param right operand
     * \brief multiplication of two real numbers
     */
    template<typename TT>
    inline TT operator*(Real<TT>const& left,Real<TT>const& right)
    {
        return left._value*right._value;
    }
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \param left operand
     * \param right operand
     * \brief multiplication of two real numbers
     */
    template<typename TT>
    inline TT operator*(TT const& left,Real<TT>const& right)
    {
        return left*right._value;
    }
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \param left operand
     * \param right operand
     * \brief multiplication of two real numbers
     */
    template<typename TT>
    inline TT operator*(Real<TT>const& left,TT const& right)
    {
        return left._value*right;
    }
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \param left operand
     * \param right operand
     * \brief division of two real numbers
     */
    template<typename TT>
    inline TT operator/(Real<TT>const& left,Real<TT>const& right)
    {
        return left._value/right._value;
    }
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \param left operand
     * \param right operand
     * \brief division of two real numbers
     */
    template<typename TT>
    inline TT operator/(TT const& left,Real<TT>const& right)
    {
        return left/right._value;
    }
    ////////////////////////////////////////////////////////////////////////////////
    /*!
     * \param left operand
     * \param right operand
     * \brief division of two real numbers
     */
    template<typename TT>
    inline TT operator/(Real<TT>const& left,TT const& right)
    {
        return left._value/right;
    }
    ////////////////////////////////////////////////////////////////////////////////
    #endif	/* _REAL_TCC */
    De la classe Real<double> hérite une classe DoubleReal représentant les flottants à précision double :
    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
     
    #ifndef _DOUBLEREAL_HPP
    #define	_DOUBLEREAL_HPP
    #include "Real.hpp"
    /*! 
     * \class DoubleReal
     */
    class DoubleReal : public Real<double>
    {
    public:
        DoubleReal(double const&);
    };
    ////////////////////////////////////////////////////////////////////////////////
    #include "DoubleReal.tcc"
    #endif	/* _DOUBLEREAL_HPP */
    Le fichier DoubleReal.tcc est aussi vide que DoubleReal.hpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #ifndef _DOUBLEREAL_TCC
    #define	_DOUBLEREAL_TCC
    inline DoubleReal::DoubleReal(double const& value)
    :Real<double>(value)
    {}
    #endif	/* _DOUBLEREAL_TCC */
    Lorsque je mesure le temps mis pour faire plusieurs sommes de doubles, par exemple avec le code
    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
     
    #include <cstdlib>
    #include <iostream>
    #include "Dataset.hpp"
    #include "KMeans.hpp"
    #include "Profiler.hpp"
    #include "DoubleReal.hpp"
    /*
     * 
     */
    int main() {
     
        double a = 1.0;double b = 2.0;
     
        unsigned int m=100000;
        unsigned int n=100000;
        Profiler prf; // classe permettant de mesurer le temps CPU
        double tmps = prf.cputime();
        for (size_t i=0;i<m;++i)
        {
            for (size_t j=0;j<n;++j)
                a=a+b+b;
        }
        tmps = prf.cputime()-tmps;
     
        std::cout<<"elapsed CPU time : "<<tmps<<std::endl;
     
     
        return (EXIT_SUCCESS);
    }
    j'obtiens 4 secondes de calcul (g++ -O3).
    Si je remplace la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    double a = 1.0;double b = 2.0;
    par la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DoubleReal a = 1.0;DoubleReal = 2.0;
    je mesure le même temps.

    La mauvaise nouvelle est que je n'ai pas déclaré de destructeur dans les classes Number et Real<T>. J'imagine que par défaut ils sont privés et non virtuels alors qu'ils devraient être publics et virtuels ou protégés et non virtuels si j'en crois l'article de la faq.

    Saut que si je déclare ces destructeurs autrement, je perds énormément en performances. Par exemple, pour la classe Number, si j'ajoute
    mon temps de calcul passe de 4 secondes à 54 secondes!!!
    C'est d'ailleurs pour cela que mes constructeurs sont déclarés protégés dans les classes Number et Real<T>... mais j'aurais préféré faire des classes abstraites.

    Quelqu'un sait-il comment contourner le problème?

  2. #2
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    1. Quel compilateur utilises-tu?
    2. Est-ce que tu mesures les performances en mode Debug?

  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,

    A vrai dire, je me demande honnêtement s'il est réellement opportun d'essayer de faire hériter ta classe template Real<T> de number...

    Si on peut, effectivement, dire que tout réel est un nombre (du moins au sens mathématique du terme), et que l'on peut en dire autant pour les entiers, l'héritage n'aurait, à l'extrême limite, un intérêt que dans le sens où... tu voudrais faire cohabiter des entiers et des réels dans une même collection en les faisant passer pour... des nombres.

    Le problème, c'est que ta classe nombre, elle n'est pas vraiment très utile dans cette optique, au vu de sa forme actuelle

    Et il ne faut pas oublier les incompatibilités dues aux limites des différents types de valeurs numérique, qu'il sera difficile de gérer (faire entrer un short dans un int, c'est pas un problème, mais faire rentrer un int dans un short, ca nous fait perdre des informations )

    Tu ne pourrais t'en sortir, aussi bien pour récupérer les fonctions / opérateurs intéressants que pour éviter les incompatibilités de types qu'à coup de downcast... Est-il utile de te rappeler que c'est rarement une solution

    Il y aurait bien sur la solution de passer par un patern visiteur, pour autant que cela ait un sens
    Tu pourrais donc avoir quelque chose comme
    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    class Visitor;
    class Number
    {
        public:
            virtual void accept(Visitor const & v) const = 0;
            virtual ~Number() = 0;
    };
    Number::~Number(){}
    template <class T>
    class Real :public Number
    {
        public:
            typedef T value_type;
            Real(T t):t_(t){}
            ~Real(){}
            void accept(Visitor const &) const;
            value_type value() const{return t_;}
        private:
            T t_;
    };
    class Visitor
    {
        public:
            void visit(Real<double> const & r) const
            {
                std::cout<<"this use a double :"<<r.value()<<std::endl;
            }
            void visit(Real<float> const & r) const
            {
                std::cout<<"this use a float :"<<r.value()<<std::endl;
            }
            void visit(Real< long double> const & r) const
            {
                std::cout<<"this use a long double :"<<r.value()<<std::endl;
            }
    };
    template<typename T>
    void Real<T>::accept(Visitor const & v) const
    {
        v.visit(*this);
    }
    typedef Real<float> FloatReal;
    typedef Real<double> DoubleReal;
    typedef Real<long double> LongDoubleReal;
    struct Deleter
    {
        void operator()(Number *t)
        {
            delete t;
        }
    };
    struct VisitIt
    {
        VisitIt(Visitor const & v):v(v)
        {
     
        }
        template<typename T>
        void operator()(T * ptr)
        {
            ptr->accept(v);
        }
        Visitor const & v;
    };
    int main()
    {
        std::vector<Number*> tab;
        tab.push_back(new FloatReal(12.123));
        tab.push_back(new DoubleReal(45.456));
        tab.push_back(new LongDoubleReal(78.123));
        Visitor v;
        std::for_each(tab.begin(), tab.end(),VisitIt(v));
        std::for_each(tab.begin(), tab.end(), Deleter());
        return 0;
    }
    Mais, pour ce qu'il en est des opérateur mathématiques...

    N'oublie pas que l'héritage publique est généralement incompatible avec la sémantique de valeur, qui est nécessaire pour pouvoir les implémenter
    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
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Je suis surpris mais comme Klaim je me demande quelle version de gcc tu utilises et quelles sont tes options de compilation ?
    Si j'en suis la logique de ce que tu as déjà fait, passes en protégé ton destructeur dans la classe Number et inline public dans DoubleReal.

  5. #5
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Bonjour,

    merci à tous pour vos réponses.

    Le compilateur :

    j'utilise g++ avec le tag d'optimisation -O3.
    La distribution est celle de MinGW.
    En mode debug, c'est encore pire puisque je perds en performances quoi que je fasse (normal!).
    J'ai essayé d'autres tags (-O,-O2) mais c'est -O3 le meilleur.

    Passer le destructeur de Number en protégé :

    en déclarant le destructeur de Number, mes temps de calcul explosent...

    Faire hériter des classes de Real<T> :

    La classe Real<T> n'est pas destinée à être instanciée (constructeurs protégés mais il en manque si j'ai bonne mémoire).
    Elle me sert juste à ne pas faire des copier-coller des opérateurs +,-,=,etc pour chaque type numérique (int,float,double,...).
    M'arrêter à la classe Real<T> me gêne aussi parce que je veux contrôler un minimum le type T (pour moi Real<double*> n'a pas de sens).

    Si je comprends bien, il serait finalement plus logique d'écrire chaque classe (DoubleReal,DoubleComplex,Integer,etc) quitte à perdre du temps?

    Incompatibilité entre types numériques différents :

    oui, effectivement je suis au courant pour short et int, etc.
    A priori, je n'aurai pas besoin de transtyper.

    Pattern visiter :

    très mauvaise solution pour moi car tu déclares Number en classe abstraite : je perds énormément en performances.


    En clair, si je ne laisse pas le compilateur s'occuper seul des destructeurs, je suis perdant même en utilisant le mot-clé inline.
    Si je comprends bien, l'idée selon vous est de ne pas faire d'héritage pour les sémantiques de valeur (Real<T> disparaît).
    J'ai du boulot!

    Par contre, ça ne résout pas forcément mon problème de perfs.
    Je vais vérifier.

  6. #6
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Tu peux préciser la version de GCC/Mingw stp?

    Si quelqu'un a les moyen de tester, ça ressemble énormément a un "bug" de compilateur.

    Au passage, si tu ne mets pas le ; dans le destructeur est-ce que tu retrouves les performances "normales"?

Discussions similaires

  1. Héritage SQL et performances
    Par BigFoot69 dans le forum Décisions SGBD
    Réponses: 17
    Dernier message: 18/04/2014, 17h16
  2. héritage et destructeurs virtuels.
    Par deubelte dans le forum C++
    Réponses: 19
    Dernier message: 08/04/2010, 10h42
  3. [MLD] Héritage et performances
    Par ymoreau dans le forum Schéma
    Réponses: 8
    Dernier message: 09/07/2009, 09h35
  4. Gotw #5 héritage et destructeur virtual
    Par Trunks dans le forum Langage
    Réponses: 7
    Dernier message: 07/04/2009, 14h56
  5. Thread, Héritage et Destructeurs
    Par contremaitre dans le forum Threads & Processus
    Réponses: 8
    Dernier message: 15/09/2008, 10h20

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