8
votes

Qu'est-ce que l'équivalent d'instance de Java de C ++ 11

Je veux savoir ce qu'est l'équivalent de l'instance de Java de Java de Java. J'ai vu ce donc post mais c'est assez ancien et se demandait s'il y a un plus moderne, Meilleure solution en C ++ 11?

J'espérais qu'il y avait une possibilité d'utiliser une construction de commutation sans avoir à recourir à une classe d'Enum manuelle. P>

class A {

};

class B : public A {

}

class C : public A {

}

on_event(A& obj)
{
    switch (obj) {
       case A:
       case B:
       case C:
    }
}


8 commentaires

Demandez-vous dynamic_cast <> ? Ce n'est pas spécifique C ++ 11.


Rien n'a changé: il n'y a pas de réflexion dans la norme C ++. Si vous souhaitez activer des informations de type d'exécution, vous dynamic_cast


Peut-être d'intérêt: Stackoverflow.com/q/25495733/596781


-1 La question est maintenant absurde: vous demandez un "équivalent à Java" de quelque chose qui est complètement indépendant et inacceptable avec Java.


De plus, il semble fou de vouloir réinventer manuellement quelque chose qui est résolu précisément résolu par le polymorphisme d'exécution dans la langue.


Je ne vois pas comment c'est "absurde" et que vous rencontrez comme impoli pour moi. Je veux connaître le meilleur moyen d'implémenter ma fonction ON_Event pour gérer les différentes sous-classes qui ne disposent pas de méthodes / membres virtuels dans la classe de base (A). Je sais comment je le ferais en Java, mais je veux connaître le meilleur moyen de C ++.


"Ma classe de base n'a pas de méthodes virtuelles ou de fonctions" et "la classe de base n'est qu'un porte-polymorphe" semble contradictifier des déclarations. Étant donné que a est une classe de base elle devrait avoir un destructeur virtuel . Cela ressemble à un problème xy quand même, il est probable que vous puissiez éviter l'instruction commutateur à l'aide de fonctions virtuelles.


En dépit d'avoir été évité, je tiens à attirer votre attention sur la réponse de @kastaneda, qui est définitivement utile - même si ce n'est pas pour le cas d'accéder aux sous-classes à travers un pointeur ou une référence.


5 Réponses :


12
votes

La même réponse s'applique toujours et a toujours été comme celle-ci en C ++: xxx

Cette construction nécessite A à polymorphe, c'est-à-dire avoir des fonctions de membre virtuel .

Notez également que ce comportement est différent de la comparaison de typeid (obj) == typeid (c) , puisque ces derniers tests pour l'identité de type exacte, alors que la distribution dynamique, comme Eh bien, l'instance de Java, seuls testez le type de cible pour être une classe de base du type de l'objet le plus dérivé.


17 commentaires

Il nécessite également RTTI , qui est un peu de douleur pour certains utilisateurs C ++.


@ user2485710: Je ne pense pas que cette déclaration a du sens dans le contexte de la Langue C ++. Le code est valide C ++, sans qualification.


Si vous n'avez pas RTTI Cette chose ne fonctionnera pas, peu importe ce que vous envisagez, c'est juste nécessaire pour que cette pièce de code fonctionne correctement.


@ user2485710: sur certains IDES (par exemple, Visual Studio), vous devez activer l'option RTTI dans les paramètres du projet, mais qui n'a rien à voir avec la norme de langue C ++.


@ user2485710: Il n'y a pas de telle chose en C ++. Vous ne pouvez pas «pas avoir RTTI» et avez toujours C ++.


Et si un membre n'a pas de membres de fonctions; cela fonctionnera-t-il toujours alors?


@ user8090: Non, il doit avoir au moins une fonction de membre virtuel. (En règle générale, un destructeur virtuel fournirait une fonction de membre virtuel canonique.) [[[[[[[[[On pourrait éventuellement faire un argument selon lequel si vous avez un programme qui ne nécessite pas légitimement les destructeurs virtuels, il ne nécessite pas de polymorphisme d'exécution du tout, éventuellement après un refactoring lourd.]]


@ user8090: doit avoir au moins une fonction de membre virtuel (sinon, la classe ne disposera pas d'une table V et que l'opérateur dynamic_cast ne sera pas en mesure de faire la comparaison de types).


@Kerreksb Vous ne pouvez pas "pas avoir RTTI" et avez toujours C ++ c'est une bonne approche de la vie en général, trop beau pour être vrai.


Je vais modifier ma question car ma classe de base n'a pas de membres virtuels ni de fonctions.


@ user8090: ne fais pas ça. Cela rendrait la question absurde. Vous demandez un équivalent Java, mais tout en Java est polymorphe. Demandez une nouvelle question si vous avez besoin de résoudre quelque chose de C ++ spécifique.


Étant donné que cette question est étiquetée c ++ 11, vous pouvez remplacer c * avec auto ;)


@FredOverflow: C'est une mauvaise hygiène de masquer les pointeurs dans les alias de type, alors au mieux, vous devez dire auto * . Je suis au courant de cela, mais j'ai figuré c * est un peu plus court et plus propre dans ce cas.


@Kerreksb heh vous devriez dire à Microsoft. Littéralement, chaque pointeur de l'API Win32 est caché dans un alias de type.


Ne devrait-il pas être si (C * p == dynamic_cast (& obj)) avec deux ='s?


@LegionDaeth: Non, ce ne serait pas une syntaxe valide, ni cela ne serait pas significatif. Qu'est-ce que p ?


@Kerreksb NeverMind, mal compris ce qui se passait, tu as raison.



-1
votes

Si vous êtes prêt à vous limiter à des types connus au moment de la compilée (plutôt que de travailler via des pointeurs sur des instances de classes avec VTables) - alors C ++ 11 et ultérieure dispose d'une instance Équivalent: C'est std :: is_base_of .

Vous voudrez peut-être aussi consulter std :: is_convertible et std :: isame .


2 commentaires

Je ne sais pas comment cela l'aide à moins qu'il en fait un modèle de fonction et connaît les types à la compilation. Je pense qu'il est assez clair qu'il parle de polymorphisme d'exécution


@PETERT: Complètement désaccord. C'est-à-dire en C ++, surtout moderne C ++, nous faisons un lot entier avec des types de compilation-hétéro, il s'agit donc d'une réponse parfaitement valide (même si elle devrait être éditée).



0
votes

in c ++, anciennes données (POD) ne contient aucune information de type d'exécution. Les classes ont décrit tous prennent exactement 1 octet et présentent des représentations d'exécution identiques dans n'importe quel compilateur avec l'optimisation de la classe de base vide.

comme tel ce que vous voulez ne peut pas être fait.

Ajout d'un destructeur virtuel à la base La classe ajoute en RTTI et dynamic_cast prise en charge.

Ajout d'un Enum ou int sur la base qui est initialisée différemment Pour chaque classe dérivée fonctionne également.

Une autre option consiste à créer une fonction de modèle et à stocker un pointeur, comme: xxx

et Ensuite, stockez un my_type_id dans A initialisé de manière appropriée. Ceci réinventer RTTI, et comme vous le souhaitez plus de fonctionnalités, vous approcherez des frais généraux C ++ RTTI.

en C ++, vous ne payez que ce que vous demandez: vous pouvez demander des cours sans RTTI, que vous avez fait et obtenez IT.

RTTI est une information sur le temps d'exécution. POD est des données anciennes simples, un terme C ++ 03. De nombreuses classes ne sont pas pod: le moyen facile consiste à ajouter un destructeur virtuel . C ++ 11 a plus de mise en page standard et de termes agrégates à grain fin.

Techniquement RTTI et POD ne sont pas des opposés les uns des autres: il y a des classes sans RTTI qui ne sont pas pod.

Notez que MSVC a des options pour ne pas générer RTTI et son pliage de COMDAT agressif peut casser le manuel RTTI que j'ai fait ci-dessus, dans les deux cas en violation de la norme.


0 commentaires


0
votes

Peut-être que vous êtes intéressé par la réponse que j'ai postée à l'intérieur de votre vieux message mentionné.

https://stackoverflow.com/a/49296405/1266588

La réponse présente une implémentation de instance de sans l'utilisation de dynamic_cast basé sur C ++ 11, Modèle MetaProgramming et RTTI . Une application de mesure de la petite performance démontre qu'il est plus efficace que dynamic_cast si vous utilisez optimisation du compilateur.


0 commentaires