[C++] template<int>class ...

Résolu/Fermé
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 - 21 mai 2009 à 13:50
mamiemando Messages postés 33093 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 4 mai 2024 - 23 mai 2009 à 00:37
Bonjour,

Je suis en vacances, mais je voudrais en profiter pour consolider certains points tant que c'est encore frais !!!
Je commence un projet de calcul de grands nombres, mais je voudrais le faire avec des template<int n> où n est le nombre de bits du nombre...

Seulement voilà, on a vu les template très vite à la fin de l'année et je voudrais partir sur de bonnes bases, si quelqu'un pouvait m'expliquer les erreurs sur mes constructeurs et destructeurs ce serait sympa...
#include <iostream>

template <int nbBit> class gdnombre
{
         private: bool T[nbBit];
                  bool S;       // signe : 0 positif, 1 négatif
         public : gdnombre();
                  gdnombre(&gdnombre<n>);    
                  ~gdnombre();  
};

gdnombre<nbBit>::gdnombre()
{
    for (int i=0; i<nbBit; i++)
    {
        T[i]=false;
    }
    S=false;
    cout << "creation : " << nbBit << endl;
}

gdnombre<nbBit>::gdnombre(&gdnombre<n> g)
{
    if (nbBit<=n)
       for (int i=0; i<nbBit; T[i++]=g.T[ifalse);  
    else
       for (int i=0; i<nbBit; T[i++]=g.T[ifalse);  
    S=g.S;       
    cout << "copie : " << nbBit << "," << n << endl;
}

gdnombre<nbBit>::~gdnombre()
{
    cout << "destruction : " << nbBit << endl;  
}                                                

int main()
{
    gdnombre<6> a;     // creation : 6
    {
       gdnombre<3> b;  // creation : 3
       a=b;            // copie : 6,3
    }                  // destruction : 3
    
    system("PAUSE");
    return 0;    
}

9 réponses

mamiemando Messages postés 33093 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 4 mai 2024 7 752
21 mai 2009 à 23:10
Ci-dessous un petit topo sur les templates (dont ceux paramétrés par des entiers) :
http://www.commentcamarche.net/faq/sujet 11194 les templates en c

Si tu ne t'en sors pas donne le code complet du cas qui te pose problème.

Bonne chance
1
mamiemando Messages postés 33093 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 4 mai 2024 7 752
22 mai 2009 à 00:52
Plutôt que de redéfinir le cast ça me paraît moins dangereux de redéfinir l'opérateur =. Le problème c'est que si tu redéfinis le cast tu risques d'avoir des ambiguïté dans ton code.
class pouet_t{
    protected:
        int x;
    public:
        explicit pouet_t(int x0 = 0):x(x0){}

        inline int get_x() const{
            return x;
        }

        inline int operator=(int x0){
            x = x0;
            return x;
        }
};

Bonne chance
1
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
22 mai 2009 à 12:51
J'ai l'impression que inline fait exactement le contraire de virtual mais alors je ne vois pas l'intérêt de l'utiliser...

Pour le cast j'ai trouvé ici comment il faut faire...
#include <iostream>
using namespace std;

class pouet_t{
    protected:
        int x;
    public:
        explicit pouet_t(int x0 = 0):x(x0){}

        inline int get_x() const{
            return x;
        }
        
        inline int operator=(int x0){
            x = x0;
            return x;
        }
        
        operator int() {
            return x;
        }    
};

int main()
{
    pouet_t p(3);
    cout << p.get_x() << endl; // 3
        
    p=5;
    cout << p.get_x() << endl; // 5
    
    int i=p+3; 
    cout << i << endl; // 8
    
    system("PAUSE");
    return 0;
}
1
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
22 mai 2009 à 13:43
Du coup avec ma classe j'arrive à faire ce que je voulais
    gdnombre<16> a;    
    a=3647;
    
    gdnombre<32> b;
    b=a;
    
    gdnombre<8> c;
    c=a;

    double d;
    d=a;
Problème résolu ! Merci...
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
21 mai 2009 à 19:33
Finalement, en bidouillant (beaucoup) j'ai réussi à trouver mais j'ai un autre problème...

Comment paramétrer un cast dans ma classe ? Par exemple :
gdnombre<5> N;
int i;
i = (int) N;
Si je fais ça j'ai une erreur sur la ligne 3, `class gdnombre<5>' used where a `int' was expected

Cependant je voudrais que ce genre d'opération soit valide avec ma classe
Mais j'ai besoin qu'on m'explique comment il faut faire...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
21 mai 2009 à 23:24
Avec les template je crois que je vais m'en sortir, je bloquais parce que je ne savais pas qu'il fallait redonner la définition du template à chaque fois qu'on implémentait une méthode...

Par contre pour mon problème de cast ça reviendrait à avoir ce code là :
class Exemple
{
      private: int Entier;
      public : Exemple(int i=0)
               {
                   Entier=i;
               }
};

int main()
{
    Exemple e(5);
    
    int i=e;   // cannot convert `Exemple' to `int' in initialisation
    i=e;       // cannot convert `Exemple' to `int' in assignment
    i=(int) e; // `class Exemple' used where a `int' was expected 
    
    system("PAUSE");
    return 0;
}
Je comprends les erreurs mais je voudrais faire en sorte que les conversions soient autorisées et je ne sais pas comment faire...
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
22 mai 2009 à 01:07
Ok, merci, je vais voir ce que ça peut donner...
Mais il va d'abord falloir que je regarde à quoi servent explicit et inline parce que j'en ai aucune idée ^^
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
22 mai 2009 à 01:33
Avec le code que tu m'as donné j'ai
pouet_t p;
int i;

p=i; // ok
i=p; // cannot convert `pouet_t' to `int' in assignment
Comment faire ? J'ai essayé avec friend mais j'arrive pas à débuger
 friend int int::operator=(pouet_t p){
            return p.x;
        }
0
mamiemando Messages postés 33093 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 4 mai 2024 7 752
22 mai 2009 à 11:54
explicit permet d'éviter les ambuiguïté (c'est-à-dire que le constructeur n'est appelé que si le type des paramètre concorde exactement). Lorsque ton constructeur prend en paramètre juste un entier c'est bien de le mettre.

Le mot clé inline est expliqué ici :
http://www.commentcamarche.net/faq/sujet 11250 les inlines en c

Par rapport à l'opérateur que tu redéfinis, tu n'as pas besoin de friend si tu mets un accesseur dans ta classe (l'équivalent du get_x dans le code que je t'ai indiqué). De manière général tu devrais te servir le moins possible du mot clé friend.

Pour l'opérateur d'égalité dans l'autre sens c'est malheureusement plus compliqué. Outre le fait que ton opérateur ferait mieux de manipuler une référence vers p plutôt qu'une recopie (c'est-à-dire qu'au lieu de recopier dans la pile l'objet p qui peut être gros, on se contente de mettre son adresse, et on précise const car cet objet n'est pas modifié par l'opérateur =).

Par exemple l'opérateur = que je t'ai indiqué peut également s'écrire :
inline int pouet_t::operator=(pouet_t & p,int x0){
  p.set_x(x0); // il faudrait rajouter un accesseur en écriture
  return x;
}

Ici bien entendu on manipule un "pouet_t &" et non un "const pouet_t &" car p est modifié.

Le problème avec int c'est que ce n'est pas une classe mais un type de base et que tu l'écris comme si ton opérateur = avait déjà été déclaré. Et je ne sais pas comment on fait pour écrire l'opérateur = dans ce sens :s Essaye de voir si on peut redéfinir l'opérateur = pour les types de bases et/ou redéfinir un opérateur de cast en C++ mais franchement je ne suis pas super convaincue :s

Bonne chance
0
mamiemando Messages postés 33093 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 4 mai 2024 7 752
23 mai 2009 à 00:37
Ok merci pour l'opérateur de cast, je ne connaissais pas la syntaxe.

Le inline n'a rien à voir avec virtual. Pour faire simple, ces deux mots clés peuvent être vus comme suit :

- inline permet de remplacer chaque appel de la fonction inline par le corps de cette fonction. Cela signifie qu'une fonction implémentée dans un .hpp mais inline ne risque à aucun moment de provoquer une multi définition. Le inline permet d'avoir un exécutable plus rapide mais un peu plus volumineux.

- virtual permet d'activer le lien dynamique, qui n'est pas activé par défaut en C++ pour des raisons de performances.

Bonne chance
0