OVH Cloud OVH Cloud

Java vs C++

55 réponses
Avatar
Zouplaz
Bonjour, est-ce que quelqu'un aurait un lien vers une page expliquant
clairement les avantages du C++ (en terme POO) par rapport au à Java.



Merci

10 réponses

1 2 3 4 5
Avatar
Richard Delorme

Arnaud Debaene - :

Si tu parles purement de POO, les différences les plus notables que je
vois sont :

- Garbage Collector en Java, ce qui entraine malheureusemeent qu'il
n'y a pas de vrai destructeur en Java et qu'il est donc difficile de
gérer proprement la durée de vie des ressoureces autres que la mémoire
(en C++ on utilise l'idiome RAII). Un effet de bord annexe est qu'n
Java on ne peut pas choisir de manipuler soit une valeur soit une
référence (ou pointeur) comme on peut le faire en C++.




Alors JUSTEMENT ! Je ne vois pas comment on peut concevoir de travailler
sans concepts de référence et encore moins de pointeurs (qui sont à
bannir en C++, vous me l'avez si souvent dit !)...

Comment peut-on s'en sortir avec des copies d'objets !! Je trouve ça plus
que problématique !


En java, les objets sont systématiquement passés par référence, et non par
copie, sauf les types natifs (boolean, int, ...).


Exemple : <snip exemple>

Suis-en train de me fourvoyer ?


Oui.

--
Richard


Avatar
Arnaud Meurgues
Christophe Brun wrote:

3 - pas de templates en JAVA (donc pas de STL et pas de
métaprogrammation...)


C'est prévu dans java 1.5.

Arnaud

Avatar
Arnaud Meurgues
Zouplaz wrote:


Alors JUSTEMENT ! Je ne vois pas comment on peut concevoir de travailler
sans concepts de référence et encore moins de pointeurs (qui sont à
bannir en C++, vous me l'avez si souvent dit !)...

Comment peut-on s'en sortir avec des copies d'objets !! Je trouve ça plus
que problématique !


Java, justement, n'utilise *que* des références.

Par ailleurs, il y a des types de classe pour lesquels il est plus
naturel d'utiliser une sémantique de valeur.

class piece_maison
{
public void addMobilier(mobObject mob)
}

Là c'est typique, l'objet mobilier une fois associé à une instance de
piece_maison en sera définitivement prisonnier ! S'il est modifié par
ailleurs ça finira aux oubliettes.


Non. En Java, mobObjet désigne en fait une référence.

class piece_maison {
public void addMobilier(mobObject mob)
}

s'écrit en C++

class piece_maison {
public:
void addMobilier(monObject& mob);
}

Concevoir qu'un objet (une instance) puisse avoir une vie propre, soit
totalement autonome de son container me semble indispensable (mais je
peux me tromper, c'est là que ça devient conceptuel).


Oui, c'est indispensable et c'est ce que fait Java. En revanche, Java ne
permet pas de concevoir qu'un type n'a pas de raison de donner une
identité à ses instances (mais fait une entorse pour les types de base).

Par exemple, une date, c'est plus une valeur qu'un chose qui peut
varier, de la même manière qu'un int.

Ainsi, en C++, il n'est pas anormal d'écrire :

class Livre {
public:
void DateEdition(Date d);
}

Il n'y a pas lieu d'utiliser une référence ici, car la date est une
valeur, et non un objet susceptible d'être modifié.

James avait aussi utilisé l'exemple d'une classe gérant des valeurs
monnaitaires. Une somme d'argent, c'est une valeur. Ça n'a pas de sens
de donner une identité à une somme d'argent.

Suis-en train de me fourvoyer ? J'ai quand même du mal à imaginer que le
concept de référence si important en C++ soit finalement un gadget dont
on aurait pu se passer...


C'est le contraire : Java a retenu le concept de référence et jeté celui
de valeur.

Arnaud

Avatar
Arnaud Meurgues
wrote:


L'absence des destructeurs en Java est palié par les blocs finally. Que
l'utilisateur oublie systèmatiquement à mettre:-)


L'intérêt en est quand même relatif puisqu'on n'a pas l'assurance qu'un
bloc finally sera appelé.

1. C++ supporte une sémantique de valeur aussi pour les types définis
par l'utilisateur. Gosling a proposé un tel support en Java, mais
pour l'instant, rien ne s'est fait.


Du genre de ce que fait C# ?

Arnaud

Avatar
Arnaud Meurgues
Arnaud Debaene wrote:


Bien sûr, et ca existe en Java : ca s'appelle les finaliseurs. Le gros
problème est qu'ils sont appelés par le GC quand il détriut l'objet,
ce qui signifie que tu ne sais pas quand il est appelé ni dans quel
ordre.


Ni même s'ils seront appelés.

Arnaud

Avatar
Luc Hermitte
Richard Delorme wrote in
news:3f696b48$0$20947$:

En java, les objets sont systématiquement passés par référence, et non
par copie, sauf les types natifs (boolean, int, ...).


Pas exactement car _tout_ est passé par valeur en Java ; et il n'y a pas
d'exception. C'est juste que les types "référence" sont en fait des
pointeurs vers des endroits qui contiennent plus que les objets (ie: nombre
des références qui pointent là et probablement une ou deux autres infos).

--
Luc Hermitte <hermitte at free.fr>
FAQ de <news:fr.comp.lang.c++> :
<http://www.cmla.ens-cachan.fr/Utilisateurs/dosreis/C++/FAQ/>
Dejanews : <http://groups.google.com/advanced_group_search>

Avatar
kanze
(Arnaud Debaene) wrote in message
news:...
"Alain Naigeon" wrote in message
news:<3f68d0f2$0$10431$...
"Arnaud Debaene" a écrit dans le message
news: 3f68cd83$0$2787$

- Garbage Collector en Java, ce qui entraine malheureusemeent
qu'il n'y a pas de vrai destructeur en Java


Ce qui entraîne..? Bon, il me semble qu'on peut imaginer de
spécifier des destructeurs pris en compte par un Garbage collector
(sans pour autant déclencher soi-même leur exécution).


Bien sûr, et ca existe en Java : ca s'appelle les finaliseurs.


Qui n'ont rien à voir avec les destructeurs.

Le gros problème est qu'ils sont appelés par le GC quand il détriut
l'objet, ce qui signifie que tu ne sais pas quand il est appelé ni
dans quel ordre.


Le gros problème, effectivement, c'est qu'ils seront appelés par la
ramasse-miettes. Ça sert éventuellement à signaler des erreurs, mais pas
à écrire un code correct.

L'idiome de Java qui remplace les destructeurs, ce n'est pas finalize,
mais les blocs finally. Avec une mode d'emploi bien autre, et bien moins
sûre, que les destructeurs.

Imagines par exemple un objet "o_file_stream" gérant un fichier en
écriture. Cet objet contient en interne un objet "buffer" pour des
raisons de performances. La question est : comment s'assurer que
toutes les données sont bien écrites sur le disque au moment où
l'objet o_file_stream est détruit?


L'exemple est mal choisi, je crois. S'il faut s'assurer que tous les
données soient sur disque, il ne faut attendre ne finalize (en Java), ne
le destructeur en C++ (parce que qui dit écrire dit erreur potentiel, et
comment vas-tu traiter l'erreur dans le destructeur ?).

Tu ne peux pas faire un "flush" du buffer dans le fichier physique
dans le finaliseur de o_file_stream car :
- tu ne sais pas quand (ni si) le finaliseur est appelé.
- tu n'as aucun moyen de savoir si le finaliseur du buffer n'a pas
déjà été appelé avant.

Conclusion : le code client doit appeler close sur le o_file_stream :
tu ne peux pas te reposer sur le finaliseur pour flusher le fichier
sur disque.


En somme, dans ce cas-ci, c'est exactement comme en C++. Voire même...

Dans ce cas précis, Java a même l'avantage, parce qu'il offre la
possibilité de s'assurer que les données ont été écrites, ce qui est
impossible dans le C++ standard.

Ca rend également impossible l'écriture de classes utilisant l'idiome
RAII comme ce genre de choses en C++ :

class MutexLocker
{
private:
Mutex m_mut;
public:
MutexLocker(const Mutex& m) : m_mut(m)
{
m_mut.Lock();
}

~MutexLocker()
{
m_mut.Unlock();
}
};


Mais cette faiblesse-là ne tient pas tellement de la ramasse-miettes,
mais du fait qu'il n'y a qu'une sémantique de référence.

Et là aussi, tu as mal choisi l'exemple, parce que les mutex en Java,
c'est géré au niveau du langage, avec à peu près la sémantique de RAII
en C++. (En revanche, si exceptionnellement, il te faut un verouillage
dont la durée ne correspond pas à un bloc de code, ça va poser des
problèmes en Java. Mais j'avoue que le cas ne me s'est jamais présenté
jusqu'ici.)

Si tu veux un bon exemple, pense à une transaction : un objet avec une
fonction commit, et si le destructeur est appelé avant que commit a été
appelé, il fait un roll-back (ou rien, si le changement d'état réel ne
se fait que dans le commit).

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16



Avatar
adebaene
wrote in message news:...

Une ramasse-miettes serait une bonne chose en C++, il n'y a rien à dire.
Mais soyons précis : l'existance d'une ramasse-miettes est orthogonale à
la support pour l'OO (qui semblait intéresser surtout le posteur
initial), et c'est également orthogonale à l'existance des destructeurs.

Il y a eu une proposition pour une ramasse-miettes en C++ présentée au
comité de normalisation avant la dernière norme. Les auteurs l'en ont
rétiré, parce qu'ils s'éstîmaient à l'époque que c'était trop tard, et
que essayer de l'incorporer au langage aurait rétardé la norme. Je ne
l'exclurais pas d'office dans la prochaine version de la norme, même si
d'autres évolutions semblent en avoir réduit l'importance.


Quel serait le mode de fonctionnement de ce GC? Quand seraient appelés
les destructeurs des objets gérés par le GC, et avec quelles
contraintes? Si tu as une référence sur le sujet....

Il me semble que le "problème" du GC Java est qu'il gère
obligatoirement tous les objets (c'est lié à l'absence d'objets par
valeur).


L'absence des destructeurs en Java est palié par les blocs finally. Que
l'utilisateur oublie systèmatiquement à mettre:-) -- dans ce cas-ci, on
pourrait dire que Java et C++ offrent les mêmes possibilités, avec des
moyens bien différents, mais que la façon C++ de faire est nettement
plus robuste.
Oui : c'est anormal qu'une classe ait à se reposer sur le code client

pour garantir la libération de ses ressources privées.

- Le Java propose la notion d'interface au niveau syntaxique, mais C++
permet de faire exactement la même chose (et même mieux, voir tous les
posts de James sur la programmation par contrat ou par interface) avec
des classes virtuelles pures.


On dit « des classes abstraites ». Ce sont les fonctions qui sont
virtuelle pures. :-)
Oups, au temps pour moi ;-)


- En Java, tout le monde hérite d'Object. Il y a du pour et du
contre...


Intéressant. Je n'ai pas encore trouver du pour.
Il me semble que ca simplifie la sérialisation entre autres.


Arnaud


Avatar
kanze
Arnaud Meurgues wrote in message
news:<3f696e6c$0$2787$...
wrote:

L'absence des destructeurs en Java est palié par les blocs finally.
Que l'utilisateur oublie systèmatiquement à mettre:-)


L'intérêt en est quand même relatif puisqu'on n'a pas l'assurance
qu'un bloc finally sera appelé.


Disons que c'est toujours mieux que ce qu'on a en C:-).

1. C++ supporte une sémantique de valeur aussi pour les types
définis par l'utilisateur. Gosling a proposé un tel support en
Java, mais pour l'instant, rien ne s'est fait.


Du genre de ce que fait C# ?


Je ne sais pas ce qu'on fait en C# -- jusqu'ici, il ne tourne pas sur
mon Sparc.

Pour les propositions qui concerne les types à valeur en Java, voir
http://java.sun.com/people/jag/FP.html, surtout la partie sur "Efficient
classes". Mais l'accent est sur performance et le calcul numérique -- il
ne s'adresse pas au problème de la durée de vie (que les Javaïstes
semblent ignorer complétement).

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
Arnaud Meurgues
wrote:

L'intérêt en est quand même relatif puisqu'on n'a pas l'assurance
qu'un bloc finally sera appelé.
Disons que c'est toujours mieux que ce qu'on a en C:-).



Je ne suis même pas sûr. En C, on n'a rien. On sait donc à quoi
s'attendre. En Java, on croit avoir quelque chose mais...

Je ne sais pas ce qu'on fait en C# --


Il permet de déclarer un type avec une sémantique de valeur (struct).
Ils sont stockés sur la pile pour les passages de paramètres. Mais il ne
sont pas dérivables (ce qui est rarement génant).

jusqu'ici, il ne tourne pas sur mon Sparc.


Non. Mais si tu as un linux :
http://www.go-mono.com/c-sharp.html

Pour les propositions qui concerne les types à valeur en Java, voir
http://java.sun.com/people/jag/FP.html, surtout la partie sur "Efficient
classes". Mais l'accent est sur performance et le calcul numérique -- il
ne s'adresse pas au problème de la durée de vie (que les Javaïstes
semblent ignorer complétement).


Ok. Merci.

Arnaud


1 2 3 4 5