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 :

Signification de never throw


Sujet :

C++

  1. #1
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut Signification de never throw
    bonjour

    que signifie le terme "never throw". On le voit souvent dans les librairies boost.

    http://www.boost.org/doc/libs/1_44_0...m#constructors

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Qu'il ne lancera jamais d'exception.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    Cela n'a rien a voir avec le message précédent, mais j'aimerais savoir s'il est possible de convertir un pointeur en un autre, qui n'a rien a voir. Par exemple, avec les deux classes suivantes: A et B. On voit que la conversion d'un objet A un élément B fonctionne. Mais la conversion d'un pointeur vers un objet A en un pointeur vers un objet B me renvoie le message:

    Error 1 error C2440: '=' : cannot convert from 'A *' to 'B *'

    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
     
    class B{
    	friend class A;
    private:
    	int Barg1;
    public:
    	B(){};
    	B(int o):Barg1(o){};
     
    };
     
    class A{
    private:
    	int arg1;
    	int arg2;
    public:
    	A(int o,int r):arg1(o),arg2(r){};
    	 operator B();
    	 operator B*();
    };
    A::operator B(){//conversion de A en B. 
    	B b;
    	b.Barg1=this->arg2;
    	return b;
    }
     
    A::operator B*(){//conversion de A* en B*. 
    	B b;
    	b.Barg1=arg2;
    	return &b;
    }
     
    void main(){
       A g(2,3);
       B f;
       f=g;//OKKKKKKKK
     
     
     
       A* ptra=new A(2,3);
       B* ptrb=0;
       ptrb=ptra;  ////pas okkkkkkkkkk
    }

    Alors est il possible de faire cela?
    Merci

  4. #4
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Plusieurs remarques.

    Intérêt de pouvoir faire ca ? les conversions pointeurs<->pointeurs sont en général à moitié casse geule (surtout en cas de downcasting) mais je vois _vraiment_ pas l'intérêt de faire du cross-casting (pas d'autres terme sous le clavier)

    Dans A::operator B*, tu renvois l'adresse d'une variable locale. Dans l'hypothèse où ton code serait juste, si tu la récupérerais et que tu l'utilisais: boom.

    Enfin, il faut comprendre que tes fonctions de conversions sont pour que des OBJETS se transforme en pointeur. Là tu essayes d'affecter un PoINTEUR à un autre pointeur d'un type différent sans lien d'héritage quelconque entre tes cllasses. Ca coince et c'est normal. ptrb=*ptra; marchera beaucoup mieux.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  5. #5
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    en fait, il suffit de faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     B* aa=0;
       aa=(B*)(&g);
    Dans A::operator B*, tu renvois l'adresse d'une variable locale. Dans l'hypothèse où ton code serait juste, si tu la récupérerais et que tu l'utilisais: boom.
    exacte


    Enfin, il faut comprendre que tes fonctions de conversions sont pour que des OBJETS se transforme en pointeur. Là tu essayes d'affecter un PoINTEUR à un autre pointeur d'un type différent sans lien d'héritage quelconque entre tes cllasses. Ca coince et c'est normal. ptrb=*ptra; marchera beaucoup mieux.
    c'est pas un peu ce que tu fais quand tu transforme un double en int? Il n'y a a priori pas de relation d'héritage.

  6. #6
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    en fait, il suffit de faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     B* aa=0;
       aa=(B*)(&g);
    Là tu forces le cast avec un cast C-like. ces derniers sont à bannir car tu peux faire tout et n'importe quoi. Surtout n'importe quoi d'ailleurs.

    Dans le cas où tu écris A::operator B*, tu considères que TOUT objet de type A peut être converti en un pointeur de type B.

    Si tu veux juster caster pour un objet particulier, utilise reinterpret_cast.


    c'est pas un peu ce que tu fais quand tu transforme un double en int? Il n'y a a priori pas de relation d'héritage.
    Pas pareil. Ce sont deux types définis par la norme et je ne serais pas étonné que les conversions autorisées soit explicitées dedans.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  7. #7
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    Je sais bien que mon code est pas bon, même s'il compile. Mais c'est pour m'entraîner.

    en fait, il faut faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    A g(2,3);
    B f;
    f=g;
    B* aa=0;
    aa=(&g)->operator B *();
    Mais je voudrais savoir s'il est possible de ne pas avoir a écrire ->operator B*() et avoir une syntaxe plus rapide pour appeler la conversion.

    Dans la doc d'un shared_ptr, il est écrit:


    template<class Y> explicit shared_ptr(Y * p);
    Requirements: p must be convertible to T *. Y must be a complete type. The expression delete p must be well-formed, must not invoke undefined behavior, and must not throw exceptions.


    Je veux convertir un pointeur de type Y en T. Donc pour ca, j'ai crée deux classes, mais je voulais pas de conversion d'héritage.

    Marche pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     shared_ptr<B> dd(new A(3,2));
    Je pensais que la conversion pouvait se faire, sans faire appel à un operateur explicitement.

    Marche:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      shared_ptr<B> dd((new A(3,2))->operator B *());

  8. #8
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    A g(2,3);
    B f;
    f=g;
    B* aa=0;
    aa=g;
    Compile tout aussi bien. Car en faisant (&g)->operator B*(), tu prends l'adresse de g pour ensuite la déférencer ! Autant directement prendre l'objet de base !!!

    Je veux convertir un pointeur de type Y en T. Donc pour ca, j'ai crée deux classes, mais je voulais pas de conversion d'héritage.
    Répond clairement ! QUEL INTERET as tu de faire ca ? Pourquoi essayer de déguiser un pointeur de type A en un pointeur de type B alors que B et A n'ont RIEN en commun ?
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  9. #9
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    Répond clairement ! QUEL INTERET as tu de faire ca ?
    A part manipuler du C++, aucun.

  10. #10
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Tu ne dravis jamais avoir à faire de tel cast, si c'est le cas c'est qu'il y a très probablement un problème en amont. Et au cas où il n'y aurait aucun problème, un cast entre deux type sans rapport c'est reinterpret_cast (David l'a dit je crois).

  11. #11
    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,

    Il faut comprendre que la conversion de type devrait être considérée de deux sémantiques clairement distinctes
    un type peut avoir sémantique de valeur
    un type peut avoir sémantique d'entité

    Tu as donc quatre possibilités distinctes:

    Soit tu travailles avec des types ayant sémantique de valeur, et tu souhaite pouvoir convertir une variable d'un de ces type (par exemple un int, mais cela peut aussi être n'importe quelle classe perso ayant sémantique de valeur ) en une variable de l'autre type (par exemple une std::string, mais, là encore, ce peut être n'importe quelle classe perso ayant sémantique de valeur ).

    Nous pourrions dire (parce que je n'ai jamais vu ce terme) qu'il s'agit d'une "conversion de facilité" ou d'une "conversion de manipulation", dans le sens où elle te permettra d'utiliser ta variable "autrement" que ce que permet son type d'origine.

    La solution pour y arriver est alors de prévoir, selon le cas, soit un constructeur particulier prenant le type d'origine comme argument soit un opérateur de conversion dans l'autre sens, en évitant à tout prix le cast C style qui ouvre réellement la porte à toutes les élucubrations.

    Soit tu travailles avec de types ayant sémantique d'entité, et tu veux pouvoir récupérer un "secrétaire" à partir d'un "employé" (pour autant que l'employé soit effectivement un secrétaire) ou, à l'inverse, pouvoir faire passer ton "secrétaire" pour un "employé".

    Tu as alors une relation forte entre un secrétaire et un employé, parce qu'un secrétaire... EST-UN employé.

    La conversion de secrétaire en employé est donc totalement implicite (pour autant que tu transmette ton secrétaire par pointeur ou par référence (constante ou non) ) et la conversion d'employer en secrétaire doit... veiller à ce que l'employé soit effectivement un secrétaire.

    La solution pour être sur de ne pas essayer de faire passer un "vendeur" (qui est aussi un employé ) pour un "secrétaire" passe alors par les cast particuliers de C++ que sont static_cast et dynamic_cast ou par le double dyspatch (pattern "visiteur" en tête de liste).

    Les deux dernières possibilités sont de vouloir convertir une variable dont le type a sémantique de valeur en une variable dont le type a sémantique d'entité et inversement (obtenir un secrétaire au départ d'une chaine de caractères ou obtenir une chaine de caractères au départ d'un secrétaire).

    Nous nous retrouvons alors de nouveau dans un contexte d'une " conversion de facilité" ou "de manipulation" que j'exposais plus haut
    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

Discussions similaires

  1. Réponses: 3
    Dernier message: 07/09/2004, 12h01
  2. [Mots cles]Signification de transient et volatile
    Par Pill_S dans le forum Langage
    Réponses: 2
    Dernier message: 14/07/2004, 11h58
  3. Réponses: 4
    Dernier message: 22/01/2004, 08h27
  4. Recherche la signification d'expressions en C
    Par sbadecoder dans le forum C
    Réponses: 16
    Dernier message: 20/08/2003, 07h35
  5. i386, x86 signification ?
    Par Thcan dans le forum Assembleur
    Réponses: 7
    Dernier message: 04/01/2003, 21h36

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