Pendant longtemps maintenant, j'ai perçu des pointeurs, SUPOSE que nous avons ces clasières: p> peut être transmis à Si je voulais faire le type de Ceci a l'air laids comme enfer pour moi. Bien sûr, je pourrais utiliser des pointeurs intelligents: p> mais les pointeurs intelligents ne sont que des emballages pour les pointeurs. P> Je voudrais savoir s'il ya un moyen de Évitez cela et utilisez des classes polymorphes sans utiliser de pointeurs. p> p> Nouveau code> et
Supprimer code> un peu inutile en C ++, sauf convention d'objets de longue durée, les références étant une alternative plus propre que convient mieux au modèle Raii. Cependant, je suis toujours incapable de déterminer comment éviter les pointeurs lors de l'utilisation de polymorphisme dynamique en C ++.
invoquer code> comme référence et il n'y a pas de pointeurs impliqués (bien, du moins du point de vue du programmeur). Cependant, l'exemple ci-dessus est essentiellement un polymorphisme statique. P>
B code> dépendant de quelque chose d'autre, je devrais utiliser des pointeurs: P> < Pré> XXX PRE>
6 Réponses :
Je ne sais pas pourquoi vous voulez éviter les pointeurs de tout type de coût. Il est absolument bon d'utiliser std :: unique_ptr code> /
std :: partagé_ptr code> (quand il y a un besoin, bien sûr).
Les pointeurs intelligents ne sont pas des "wrappers" autour des pointeurs. Ils vous ont laissé choisir entre différentes sémantiques et avoir des utilisations différentes. P>
Compte tenu de votre dernier exemple, vous pouvez éviter l'utilisation des pointeurs (bien que je ne voie pas vraiment de gros problème avec des pointeurs intelligents) ceci vous permet d'utiliser le titulaire comme-si C'était l'objet réel: p>
Bien sûr, cela fonctionnerait. Ma question était toutefois davantage sur l'utilisation de l'utilisation de Nouveau code> et
* code> du tout.
@Tibor: Eh bien, le qualificatif de type * code> ainsi que l'opérateur
* code> sont cachés b> à l'intérieur de cette installation (qui peut facilement être transformé en un modèle générique ), tout comme les pointeurs intelligents cachent leur utilisation des pointeurs bruts.
Le cas d'utilisation que vous pensez probablement est celui d'une sorte de usine em>, que vous pouvez servir parfaitement bien avec un pointeur intelligent et aucun utilisation: p> (vous devez avoir une définition de nouveau code> du tout :
make_unique code> quelque part, qui est malheureusement manquant dans la bibliothèque standard actuelle mais sera modifiée éventuellement.) P> p>
La définition de make_unique code> contient un appel à
nouveau code> cependant. Fondamentalement, vous ne pouvez pas vous échapper des pointeurs pour résoudre ce problème, bien que vous puissiez créer une variété d'abstractions jolies et utiles.
+1 Pour me faire comprendre que j'ai oublié les routines _ code> (et utilisé sale OL '
nouveau code>).
@Matthewwalton: Oui, bien sûr. Et chaque conteneur dynamique dans l'appel de bibliothèque standard appelle :: nouveau code> gauche droite et centre. Mais le point ici est d'établir un nouveau
nouveau code> - et idiom sans pointeur pour C ++! Et gardez à l'esprit la différence de sécurité d'exception qu'une fonction wrapper fait.
J'aimerais savoir s'il existe un moyen d'éviter cela et d'utiliser des classes polymorphes sans utiliser de pointeurs. P> blockQuote>
Non, voici comment le C ++ a été conçu en premier lieu. Pour éviter de trancher, vous devez utiliser des pointeurs ou des références. P>
Vous ne pouvez pas éviter les pointeurs pour cela. Si vous ne les aimez pas, C ++ ne sera pas la langue pour vous, car si vous voulez faire quelque chose de polymorphe, vous devrez utiliser des pointeurs pour passer les utilisations les plus triviales. Construire des objets sur le tas, c'est-à-dire à l'aide de Utilisez des pointeurs intelligents bien sûr, ils peuvent vraiment aider à éviter les problèmes avec des cycle de vie du pointeur, mais il y aura des pointeurs y compris quelque part quelles que soient les abstractions vraiment cool que vous finissez par utiliser. P> Nouveau code> correspond à la manière dont vous évitez la durée de vie cachée des objets construits de pile, que vous devez faire si vous souhaitez faire des choses à l'intérieur des branches conditionnelles, puis les assigner à des variables dans Une portée parentale - Si vous n'avez pas besoin de faire cela, vous n'avez pas non plus besoin de polymorphisme car vos types sont tous déterminables au moment de la compilation. Il n'y a aucun moyen de cela. P>
Plus j'y pense, plus cela fait de sens. Si les pointeurs n'étaient pas nécessaires, il faudrait avoir d'autres contraintes sérieuses aux types polymorphes pour éviter la tranchée, car Bјовић a souligné.
Il n'y a aucun moyen si vous avez besoin de créer des objets de manière dynamique et de les persister de la portée de la fonction. Le mieux que vous puissiez faire ici - masquer la création d'objets dans des pointeurs d'usine et intelligents.
Vous pouvez également envisager des objets statiques dans la fonction de fonction, mais ce n'est pas une bonne solution - vous ne pouvez créer que le nombre limité d'objets de cette façon: P >
template <class T, int Instance> T& create() { static T instance; return instance; } MyClass& obj1 = create<MyClass, 1>(); MyClass& obj2 = create<MyClass, 2>(); MyClass& obj3 = create<MyClass, 3>(); // etc
Les singletons sont généralement laids et, dans ce cas, particulièrement dangereux. C'est effectivement un générateur pour les objets d'Amost-Singleton.
@bitmask bien sûr, et c'est parce que j'ai écrit cela est possible, mais pas une bonne solution. Notez que réellement vous peut B> créer beaucoup d'objets de même type, il ne s'agit donc pas de singletons ...
Et que i> soit pourquoi je n'ai pas voté par vote. La personne qui n'est pas non plus acceptée avec mon précédent commentaire.
Si (COND) INVOKE (B (...)) Invoque (C (...)) Code>, aka style fonctionnel? Ou en C ++ 11 avec Lambdas si les parties communes sont grandes et que vous ne voulez pas de fonction globale supplémentaire pour cela.
@Xeo Cela fonctionnerait dans cet exemple spécifique, mais cela n'est pas toujours applicable.
Ce que vous appelez un polymorphisme statique n'est pas du tout un polymorphisme statique.
invoke code> ne connaît pas précisément le type de son argument. Vous seulement Pensez B> C'est un polymorphisme statique car vous pouvez voir le code et le type étant passé!
@Hbcdev je suis d'accord. Mais cela se comporte exactement comme tel et peut même être optimisé par le compilateur pour ne pas utiliser l'appel de la fonction virtuelle du tout.
@Tibor: Cela ne fonctionne pas dans les cas où vous avez besoin de stocker de manière conditionnelle un objet ou l'autre, true. Dans ces cas, vous n'allongerez pas d'utiliser des pointeurs, car ils sont essentiels au polymorphisme dynamique.
@HBCDEV: Je pense que ce que SOI signifie exclure tous les cas où la liaison dynamique pourrait être remplacée par des métaprogrammations car toutes les décisions basées sur le type de temps d'exécution peuvent être connues au moment de la compilation. La seconde Le type réel d'un objet dépend des informations d'exécution, vous perdez certaines options d'optimisation. Donc - si
quelque chose code> est un
consexpr code>, vous pourrait i> appeler ce "polymorphisme statique" de manière à parler.