8
votes

Quel est l'équivalent C ++ de java.lang.Object x = nouveau foo ()?

Quel est l'équivalent C ++ de java.lang.Object x = nouveau foo () ?


0 commentaires

4 Réponses :


21
votes

Il n'y a pas d'équivalent de cela en C ++ et il serait inutile de tenter de programmer Java en C ++. Cela étant dit, je vais aborder cela d'une perspective d'essayer d'imiter autant que possible les caractéristiques de l'affectation et l'esprit de la déclaration. Chaque façon dont je vais suggérer, a des compensations et des limitations. Les deux premiers ne sont pas vraiment idiomatiques c ++, mais il est important de savoir à leur sujet pour voir quels problèmes les deux derniers résolus.

1. Pointants vides de style C. strong> p>

Permettez-moi de commencer par le plus basique et le moins utile, un pointeur vide: p> xxx pré> tout peut être Attribué à un pointeur vide du nouvel opérateur comme neuf, le placement nouveau et similaire renvoie toujours un pointeur vide. Les inconvénients devraient être évidents: perte d'informations de type sur l'objet pointé à l'adresse. Pour un, C ++ manque de réflexion ou de tout moyen d'interroger l'objet. Vous devez conserver les informations de type dans votre tête et utiliser la coulée pour l'utiliser pour l'utiliser. Comme il n'y a pas de moyen sans danger de type à partir d'un pointeur vide, l'hilarité pourrait s'ensuivre. P>

S'il s'agissait d'un type de retour d'une fonction: p> xxx pré>

Toute auteur utilisant votre code aurait besoin de déterminer ce que devraient em> se produire. Malheureusement, souvent ce qu'ils devraient arriver et ce que vous, l'auteur, pensez être renvoyé à partir d'une fonction est très différent. P>

2. Syndicions de style C strong> p>

Si vous souhaitez vous limiter à N Types qui sont pris en charge à la place des types infinis que Java.lang.Object peut gérer alors il y a Unions . Ceux-ci peuvent contenir un ensemble de types de valeur prédéfinis sur le même espace mémoire tant qu'ils sont des fichiers de données de POD em>. Les syndicats manquent de deux choses très importantes: la capacité de savoir quelle valeur a été attribuée et la possibilité de contenir des types non-POD. Cela les explique complètement à utiliser avec n'importe quel objet avec n'importe quel type de fonctionnalité telle que std :: chaîne code>. P>

Pour clarifier ce qui précède réellement: p>

union myType{
    int a;
    char b[4];
};


10 commentaires

Je pense que vous devez vérifier votre syntaxe.


Personnellement, je ne pense pas que cela soit une bonne correspondance du code Java donné pour être décrit comme "équivalent". En Java, vous pouvez lancer en toute sécurité à partir d'un objet à quelque chose d'autre et de récupérer si la distribution n'était pas valide. Comme vous l'énoncez, en C ++, il n'ya aucun moyen de lancer de manière dynamique à partir d'un Void * .


@Chals Bailey - Malheureusement, rien comme Java.Lang.Object existe dans C ++. Ce que je jette, ce sont les meilleures choses que je connais, qui ont au moins quelques propriétés similaires.


@Fred, @Phaises: Je ne suis pas d'accord avec cela complètement. Tout d'abord, il n'y a pas d'équivalent C ++ car tout en C ++ est un objet. Cela doit être indiqué s'il s'agit d'être une FAQ.


Deuxièmement, si vous essayiez d'implémenter cette fonctionnalité en standard C ++, vous commencerez par mettre en œuvre une classe de base abstraite et dériver de cela. Cela donne la comparaison la plus directe à la question posée. Mais ce n'était même pas mentionné.


Troisièmement, la première chose qui a été mentionnée est en casting à vide * qui n'est pas une meilleure pratique généralement acceptée. Vous perdez toutes les informations de type et faites une fin sur le système de type. Vous dites ensuite "Essayez de ne pas le faire", mais comme il s'agit de la première chose à dire, elle sera prise comme "Cela devrait être votre première approche". Mais cela ne devrait même pas être mentionné dans une entrée comme celle-ci, du moins pas jusqu'à la section "Techniques avancées" plus tard


@RODRIGOB: Mon point était qu'il est illégal de faire cela lorsque le type de votre_pointer est vide * .


@John Dibling n'est certainement pas une réponse de type FAQ. S'il vous plaît ajouter votre propre réponse. Vous avez laissé un certain nombre de bons commentaires et j'ai tenté de clarifier certaines des problèmes que vous avez soulevés au-dessus sans prendre tout le contenu. Je voterais volontiers une réponse qui avait ce que vous avez laissé dans la section commentaires.


@Phaises: J'ai posté une réponse.


Et quel cas devrais-je utiliser après quand je dois revenir de Void * à foo par exemple?



4
votes

Il n'y a pas d'équivalent car Java alloue des objets d'un tas de géré, C ++ les alloue dans une mémoire non gérée. Les objets en Java sont suivis par la JVM pour la collecte automatique des ordures à l'aide de marquage et de balayage, alors que C ++ nécessite une libération explicite de toute la mémoire.

Les environnements d'exécution sont fondamentalement différents, dessinant des analogies en raison de la syntaxe similaire à la recherche d'une syntaxe.


3 commentaires

Il n'est pas vrai que C ++ nécessite une libération explicite de toute la mémoire. Dans les objets C ++ peuvent avoir une durée de stockage automatique, statique ou dynamique. Seuls ceux qui ont une durée de stockage dynamique nécessitent une libération explicite, la durée de vie et la mémoire des objets avec durée de stockage automatique et statique sont traitées automatiquement. Vous pouvez même dire que Supprimer x; détruit explicitement l'objet et que la mémoire est libérée implicitement dans le cadre de cela.


@Challes - merci pour ça. RAII basé sur la pile en C ++ est un autre exemple. Ma réponse était dans le contexte de la question (objets créés à l'aide de Nouveau X; ) et il est trop affirmé sur la généralité du comportement C ++ dans la deuxième phrase.


Java utilise Mark-and-balayage pour la collecte des ordures. Je ne suis pas sûr que le comptage de référence serait un bon terme à utiliser, car il ferait que les gens pensent qu'il gère la mémoire de la même manière à Swift, par exemple.



10
votes

Il n'y a pas directement em> équivalent à java.lang.Object x = nouveau foo () code> car en C ++, tout n'est pas un objet. Mais en fonction de la manière dont vous voulez utiliser strong> ces objet code> s, vous pouvez accomplir le même objectif.

L'équivalent le plus proche de java.lang.Object x = Nouveau FOO () Code> in C ++ est l'utilisation de Classes de base abstraites Code> ( ABC code>). Un ABC est une classe conçue pour être une classe de base à d'autres classes. Vous créez un ABC en donnant à votre classe au moins un Membre virtuel pur Fonction , et vous spécifiez que, à l'aide de cette syntaxe: p>

class Object
{
public:
  virtual int my_funky_method() = 0;
  virtual bool is_this_ok() = 0 { return false; } // ERROR: Defn not allowed here
};

int Object::my_funky_method()
{
  return 43;
}


0 commentaires

-1
votes
// Test this
namespace external
{
    template <class T>
    struct var
    {
    private:
        T *value;
    public:
        var(T *value)
        {
            this->value = value;
        };

        T operator &() {
            return this-> value;
        };
    };
}
#define var external::var<void *>
/**
  Use:
  var i = 0;
  cout << &i; // Output 0;
*/

1 commentaires

Merci d'avoir soumis une réponse. Cela pourrait aider les autres à mieux comprendre votre code si vous avez inclus une brève explication de la manière dont cela résout la question initiale.