10
votes

Surcharge C ++ Typecasting (fonctions)

Utilisation de tycastations de style C ++ (tous les 4) ressemble exactement à un modèle de fonction fort>. Par exemple,

dynamic_cast<Derived*>(p); // p is Base*


5 commentaires

Fait intéressant, certaines bibliothèques (comme Boost) utilisent cette similitude pour définir leurs propres opérateurs «casting», tels que static_pointer_cast <> .


@ ceris, ya j'ai entendu parler de certains moulages comme ça, mais ce mot clé n'est pas autorisé pour une raison quelconque !!


Mettez une règle dans votre projet que toutes les moulages auront lieu via certains modèles de transfert: "x_dynamic_cast", "x_static_cast", etc., puis recherchez n'importe quelle utilisation du réel dynamic_cast et remplacez-le. C'est l'une des caractéristiques fraîches des opérateurs de distribution «vity» en ce qu'ils sont très faciles à rechercher.


Puisqu'il y a des réponses qui couvrent à peu près la raison pour laquelle je voulais juste dire bien peut-être que cela n'est pas autorisé, mais vous pouvez remplacer dynamic_cast. Vous pouvez définir votre modèle "my_cast", puis utiliser le prétraiteur pour remplacer dynamic_cast ou reterpret_cast A..o Disons dans les bâtiments de débogage (c'est-à-dire de la même manière que vous pouvez utiliser le prétraiteur pour "Renommer" Nouveauté à Debug_New). Nous avons fait cela ajouté certains chèques de compilation dans les bâtiments de débogage liés au casting. Nous avions l'avantage que nous avions un fichier d'en-tête inclus sur tout ce que nous pouvions "#define dynamic_cast chk: my_cast 'en une seule place


L'avantage que je vois avec le préprocesseur APRACH (comparé au remplacement de la recherche et remplacer dynamic_cast avec x_my_dynamic_cast est qu'il ne force pas tout le monde dans votre équipe à écrire x_my_dynamic_cast et veille également à ce que des situations où quelqu'un oublie (ou ne sait pas encore - IE est nouveau dans l'équipe) que X_MY_DYNAMIC_CAST au lieu de dynamic_cast doit être utilisé automatiquement. Et tout le monde peut écrire le code car ils le feraient normalement ...


4 Réponses :


2
votes

Je pense que la raison est la même chose pour vous ne pouvez pas surcharger le mot-clé de langage.

En fait, vous devez les voir comme une fonction de clé de langage et non de la fonction de modèle, même si la look la même. OTOH, je ne pouvais pas imaginer quel type de catastrophe on pourrait faire en changeant la signification de cet aspect particulier C ++.

éditer
J'étais à peu près sûr que quelqu'un aurait lancé la question suivante: "Alors pourquoi vous pouvez surcharger nouveau / Supprimer ?". Je pense que la personnalisation de l'allocation de mémoire / de la répartition est quelque chose dont vous avez besoin dans certains scénarios et que les avantages de vous permettre de les surcharger l'emporter sur les risques. Je ne peux voir aucun avantage pour subvertir le système de type C ++, je ne pense pas à penser un scénario où il serait utile. Êtes-vous?


9 commentaires

Nouveau / Supprimer Sont également mot-clé de langue et PPL peut faire des catastrophes entre eux; La même chose est applicable pour la surcharge opérateur . Alors pourquoi pas Typecasts, qui ressemblent exactement à des fonctions déjà.


Shared_ptr PD = dynamic_cast > (pb)


Oui, dynamic_cast peut être optimisé si un développeur sait que sa classe est héritée par une seule autre classe (avec fonction virtuelle). Il y a beaucoup d'utilité si possible pour d'autres cases


@iammilind Si vous avez besoin d'optimiser votre code, je ne me concentrerais pas sur le type de coulée. J'ai vraiment du mal à y penser comme un goulot d'étranglement ...


@Simone, parfois, votre classe pourrait être utilisée par d'autres. Vous ne pouvez pas leur demander de ne pas utiliser dynamic_cast ; Plutôt, vous pouvez simplement le surcharger. En outre, je viens de donner un exemple .. Il peut y avoir beaucoup d'utilité.


@iammilind: Il s'agit des fonctions "Opérateur nouvel" et "Opérateur d'opérateur" qui peut être surchargé, pas les mots-clés - il n'est donc pas tout à fait la même chose.


Je vois. Quoi qu'il en soit, je pense que ce serait déroutant, de dire le moins. Par exemple, si la distribution est implicite? Appliquez-vous la surcharge ou non? Désolé mais - allément je vois votre point - je suis d'accord avec le comité standard. Je pense que lorsque vous avez besoin de vous gâcher avec le type de coulée la plupart du temps, vous avez des défauts dans votre conception que l'on pourrait contourner une telle caractéristique, ce qui provoque la conception pourrité.


@Richard: Et ce serait la fonction (fictif) fonction opérateur dynamic_cast qui serait surchargé, pas le mot-clé. Donc?


@sbi: Le premier paramètre à l'opérateur Supprimer doit être un un Void * et la sémantique est que le paramètre doit être "pris en charge" - quoi que ce soit pour le programme. Le type d'opérande utilisé dans l'expression d'origine avec 'Supprimer' est parti depuis longtemps. (Situation similaire pour opérateur Nouveau où le premier opérande doit avoir le type Taille_t qui correspond à la quantité de mémoire requise). Je ne vois pas comment le même processus pourrait être mappé sur un opérateur de fiction (ou non) dynamic_cast .



4
votes

Pourquoi est-ce non autorisé à les surcharger par la norme de langue pour une utilisation personnalisée?

Je suppose que c'est parce que le comité standard, lors de l'introduction de ceux-ci, pensait que la sémantique des quatre de ces mises est bien définie et applicable à tous les types qu'ils devraient être. Et surtout, c'est vrai.

Le seul exemple d'exemple que je connais est l'incapacité de dynamic_cast entre les instances intelligentes du pointeur: xxx

Je suppose que la capacité faire cela aurait des mérites.

Je ne sais pas si cela a été discuté par les volontaires qui ont fait tous les travaux dans le comité des normes (et je suis trop paresseux pour Google), mais si cela a été discuté (et je ' Je pense que oui), il a été rejeté soit parce que quelqu'un pensait que les inconvénients l'emportent sur les avantages, soit parce que personne n'avait trouvé le temps de faire une proposition décente et de le berger. 1


1 ne riez pas. Il y a en fait beaucoup de choses les plus d'accord, ce serait bien d'avoir, et qui ne manquent pas de se matérialiser car personne ne pouvait être dérangé de faire le travail d'écrire une proposition décente et de passer le temps nécessaire à la discussion et à l'améliorer de manière itérative jusqu'à ce qu'il soit peut être voté sur.


7 commentaires

+1, je l'ai pris sérieusement. :) Je sens que tout casting devrait être autorisé à être surchargé. Même si leurs implémentations décentes standard sont disponibles. par exemple. Je veux mettre un débogage lorsque quelqu'un essaie reterpret_cast .


@iammilind: Il ne sert à rien de surcharger, disons static_cast . Que voudriez-vous faire dans une version surchargée? Il en va de même pour réinterpret_cast . Il est là pour faire des moules peu sûres et dépendantes de la plate-forme. Que voudriez-vous ajouter à ce qu'il ne fait pas déjà? Et ne me faites pas commencer à propos de const_cast . Tout ce que je pouvais éventuellement imaginer faire avec une surcharge de cela devrait être faisable du code correct de const.)


Vous pouvez déjà affecter static_cast en fournissant un constructeur de conversion ou un opérateur de conversion à utiliser.


@Bopersson: Ouais, j'ai oublié de mentionner ça. Merci.


Je ne vois pas non plus de sens dans la surcharge statique_cast, réinterpret_cast et const_cast ... mais surcharge dynamic_cast est quelque chose que je souhaiterais aussi avoir.


Ouais, dynamic_cast serait agréable de surcharger. Il venait de courir dans ce problème lors de la création d'un conteneur pour les types polymorphes. Les autres devraient rester comme ils sont cependant, car ils n'ont pas de valeur commerciale réelle.


C'est vrai, le casting entre les pointeurs intelligents est tellement utile que C ++ 11 a introduit toute une famille de fonctions de distribution pour eux EN.CPPREFERFERATION.COM/W/CPP/MEMORY/Shared_ptr/pointer_cast



2
votes

Conversion du pointeur avec dynamic_cast code>, REINIERPRET_CAST code> et static_cast code> avoir des significations bien définies et il est probablement préférable de ne pas permettre la surcharge.
Ce serait une douleur de permettre aux utilisateurs de changer la signification de const_cast code>.

Seuls Type d'objet Casting Restes. P>

  int i; A a;
  A toA = static_cast<A>(i);  //  Casting to A \o/
  int fromA = static_cast<int>(a); // Casting from A \o/


0 commentaires

0
votes

Vous ne pouvez pas surcharger ces opérateurs. C'est sans doute, car vous ne pouvez pas changer la signification d'une telle chose fondamentale que d'autres réponses disent. (J'aime changer la signification pour + pour les entiers ou la décoration * pour générer un pointeur d'un type).

Cela vous empêche de définir votre Propres généralisations de fonctions de distribution, qui prennent une argumentation et qui rendent les choses très liées à celle-ci. En fait, je dirais que je dirais le point de vue opposé, vous ne devriez jamais utiliser les opérations de distribution de langue ( statique / dynamique / réinterpret_cast_cast_cast_cast ) sauf si vous faites des trucs assez bas niveau.

Que Vous voudriez faire probablement de définir votre propre fonction de coulée que la plupart du temps se comporte comme celles fournies par la langue, mais une fois de temps en temps, ils font quelque chose de plus spécifique à vos besoins spécifiques. Vous devez penser que cette fonction vraiment le fait et nommez-la bien. Quel type de coût d'exécution que vous pouvez vous permettre, quel type de comportement sur «échec» (exemplaire », renvoie une valeur null?), Etc.

La norme et de nombreuses bibliothèques sont remplies de telles fonctions. Parfois, ils ajoutent un comportement ajusté sur la distribution de la langue, d'autres fois, ils font plus. Quelques exemples:

https: //fr.cppreference. com / w / cpp / mémoire / partage_ptr / pointer_cast


0 commentaires