Je bouge de Java à C ++ en ce moment et j'ai des difficultés à chaque fois qu'un concept couramment utilisé dans Java ne correspond pas directement à C ++. Par exemple, en Java, je ferais quelque chose comme: bien sûr, en C ++ le fruit fruit; code> Déclaration crée un fruit. Cela signifie-t-il que je dois avoir un constructeur par défaut? Cela semble dangereux! Et si mon fruit par défaut s'est échappé? P> P>
7 Réponses :
Pour cartographier votre exemple sur C ++, vous devez utiliser un pointeur. En C ++, un objet construit est considéré comme un objet valide (par conséquent, avec référence, vous ne pouvez pas avoir NULL). P>
Utiliser Fruit * fruit = 0; ... p>
Vous pouvez avoir un objet par défaut de votre besoin ou 0 défaut de défaut si aucun test de test. P>
L'approche du pointeur serait-elle assez standard? Ou est-ce étrange pour une raison quelconque?
@John: L'approche du pointeur est standard. Il peut sembler étrange d'un programmeur Java, mais là encore, il y a des choses à Java qui ont l'air bizarre à un programmeur C ++. Si vous allez utiliser C ++, vous devez utiliser des pointeurs d'une sorte.
Ce n'est pas mauvais, mais vous devriez prendre soin de supprimer le pointeur après. Ou vous pouvez utiliser un pointeur intelligent (c'est un pointeur qui compte des références et de la suppression lorsque personne ne l'utilise plus).
@John: Les pointeurs sont fréquemment utilisés dans C et C ++ pour représenter des valeurs et des objets que mai i> ou ne sont pas i> existent. Cette épée raconte les deux manières, cependant: lorsque vous utilisez un pointeur que quelqu'un d'autre vous donne, vous vérifiez presque toujours pour vous assurer que ce n'est pas 0, ou votre programme s'écrasera si vous essayez de la désirer!
@Owen S: Les pointeurs sont courants dans C + Modern C ++, ils sont très rares et ne sont jamais vus enveloppés à l'intérieur d'un objet ou lors de l'utilisation d'une interface C. N'utilisez pas de pointeur. Les pointeurs sont mauvais car ils ont zéro la sémantique de propriété associée à eux et il n'est donc pas clair qui est le propriétaire de l'objet. Utilisez un pointeur intelligent (un pointeur partagé est essentiellement l'équivalent de l'objet Java)
@Martin: Il y a un lot i> de non-"moderne c ++" (qui a montré ce moniker quand même?) Out là et utiliser des pointeurs bruts est assez fréquent chez les codes de base modernes et non modernes se qualifier comme standard. Il existe également des endroits où les pointeurs intelligents ne sont pas la bonne solution. Et vous pouvez toujours représenter des valeurs «facultatives» avec NULL Smart Pointers, pour de nombreuses classes de pointeurs intelligents. Outre cela, je suis d'accord avec vous. :-)
@Ownen s: désolé mais je dois être en désaccord avec vous. Dans l'ancien code C et le code que je ferais des points "C avec des classes" sont courants. Mais dans le code C ++ où des exceptions sont une règle et Raii sont les pointeurs de norme sont littéralement non existants (la seule fois où j'ai vu un pointeur dans le code de production pendant 5 ans, c'est quand il est le seul membre d'une classe d'enveloppe qui gère le pointeur ). Son ok pour le Hobyiste et les débutants, mais travaillant dans de grandes équipes et en construction de bibliothèques de réutilisation professionnelle, cela ne fonctionne tout simplement pas. Passer aux pointeurs intelligents.
Votre fruit code> variable de Java est approximativement à un pointeur C ++. Vous êtes correct, vous ne voulez pas créer l'objet sur la pile, vous voulez simplement un pointeur sur le nouvel objet que vous créez. Donc, si vous changez simplement
fruit code> sur
fruit * code> Cela fonctionnera (si vous modifiez aussi le type de retour de la fonction). Rappelez-vous simplement que vous devez plus tard
Supprimer code> le pointeur que vous avez renvoyé de cette fonction, il n'y a pas de collection de déchets pour nettoyer votre
neuf p>
Les objets en Java sont représentés par des pointeurs. Comme cela est omniprésent, il n'y a pas de notation spéciale pour les pointeurs. En C ++, des objets peuvent être représentés par eux-mêmes ou par des pointeurs, il est donc nécessaire de spécifier des pointeurs lorsqu'ils se produisent.
La version C ++ de votre code est la suivante: p>
Fruit * GetFruit(std::string fruitName) { Fruit * fruit = 0; if (fruitname == "apple") fruit = new Fruit("apple"); else if (fruitname == "banana") fruit = new Fruit("banana"); else fruit = new Fruit("kumquat"); return fruit; }
Objet en Java. Sont l'équivalent des pointeurs partagés. Le retour d'un pointeur est un signe d'odeur de code ou de code C (la même chose pour moi. :-)
La voie la plus simple serait la suivante: ... et une cartographie directe serait d'utiliser un pointeur (de préférence "intelligent"): p>
Une cartographie directe est assez difficile depuis que Java utilise une collection de déchets nondéterministes, tandis que auto_ptr code> utilise la sémantique de transfert de propriété et les pointeurs bruts n'utilisent aucune gestion de la mémoire. Une variante qui pourrait être un peu moins surprenante est un pointeur compté par référence tel que
partagé_ptr code>.
C ++ vous donne beaucoup plus de mal de tête en matière de création de fruits. En fonction de vos besoins, vous pouvez choisir l'une des options suivantes:
1) Créez un fruit sur une pile et renvoyez une copie (vous avez besoin d'un constructeur de copie) et doit fournir des fruits par défaut au cas où le nom ne correspond pas au nom. : p> 2) Créez un fruit sur un tas et prenez soin de vous, qu'il pourrait y avoir NULL-POINTER renvoyé et que vous n'oubliez pas de supprimer ce fruit quelque part et de prendre soin de ce qu'il soit Supprimé une seule fois et seulement par son propriétaire (et que personne ne soin de la personne ne tient pas un pointeur sur le fruit supprimé): p> 3) et enfin, utilisez un pointeur intelligent pour éviter beaucoup de problèmes de pointeur possibles (mais prenez soin des pointeurs NULL). Cette option est la plus proche de votre expérience de programmation Java: p>
+1 Pour le numéro 3, Shared_Ptr est la réponse, votre complier a probablement une implémentation sans boost, car les Shared_Ptrs sont dans TR1.
4. Utilisez boost :: facultatif
@Mike Seymour. Jamais entendu parler de boost :: facultatif. Merci pour votre commentaire =)
en C ++ Il y a des pointeurs implicites en Java: il y a une différence entre un objet (c'est une entité en mémoire) et son adresse. En Java, vous devez créer explicitement un objet, car lorsque vous écrivez
MyClass *yourfunction(bool param) { if (param) return new MyClass(A); return new MyClass(B); }
Les objets fonctionnent un peu différemment dans Java vs en C ++. Comme vous l'avez noté, vous avez noté dans votre code pour créer un objet, puis vous exécutez le risque d'être transmis plus tard. Pour effectuer une quantité minimale de changement à votre code: Cependant, ce code entraînera l'objet lui-même (y compris toutes ses données internes) en cours de copie au rendement, ainsi que si son Copié autour d'une utilisation ultérieure. P> Pour être plus Java-esque, vous utiliseriez un Boost :: partagé_ptr code> à la place. Ensuite, vous avez affaire à un objet compté de référence, comme en Java: P>
boost::shared_ptr<Fruit> GetFruit(std::string fruitName) {
if(fruitName != "apple" && fruitName != "banana")
{
fruitName = "kumquat";
}
return new Fruit(fruitName);
}
Et si le fruit par défaut s'est échappé et terrorisé la ville? Non, sérieusement, qu'entendez-vous par «échappé»?
attaque des kumquats tueurs! i>
Sur une note plus sérieuse: quel est le problème avec les solutions en réponse à Votre question précédente ? Je suppose que je n'ai pas omis de voir comment les réponses à cette question ne répondent pas à cette question également.
@James (+1) Je suis un peu gêné de le dire, mais je n'avais même pas envisagé les deux questions liées. Je suppose que cela montre à quel point je suis avec C ++. Sur la question précédente, j'essayais de comprendre pourquoi je ne pouvais pas avoir de valeur de retour comme je le voulais et sur celui-ci, je me sentais comme si je me demandais un style de programmation. Eh bien, mauvaise excuse. Cependant, grâce à mes questions quelque peu redondantes et à une communauté très utile, je vais aller dans une réunion ici un peu avec quelque chose de très substantiel pour montrer. Assez bien considéger que je n'étais qu'un programmeur Java il y a quelques semaines.