OVH Cloud OVH Cloud

Java et C++

141 réponses
Avatar
pr.nm
Vu d'un néophyte (pas débutant, mais pas très bon), quelles
différences y a-t-il entre Java et C++, mis à part quelques petites
particularités syntaxiques (syntaxe de création d'un tableau,
l'utilisation de destructeur d'objet, l'initialisation par défaut des
champs) ? Est-ce que l'héritage multiple change vraiment quelque chose
?
Où puis-je trouver un document clair (français ou anglais) qui me
permette de faire la transition (j'ai lu un article disant que C/C++
était plus rapide que Java et nécessitait moins de lignes) ?
Merci d'avance.

10 réponses

Avatar
vclassine
Martinez Jerome wrote in message news:<bg3gl9$...
Vincent wrote:
PS: laisse tomber les posts de Dany et Jérôme Martinez, ils sont
partiellement faux (surtout ceux de Jérôme). Comme j'écris ça je vais
devoir argumenter, mais aujourd'hui j'ai la flemme alors j'attends un
peu qu'ils me hurlent dessus...
:-)


J'attend juste de savoir ce qui est faux dans ce que j'ai dit... Je suis
curieux.


ça y est je l'ai écrit...


Avatar
vclassine
(Endymion) wrote in message news:...
(Vincent) wrote in message news:...
Pour la perf il ne faut pas se leurrer la vitesse d'éxécution d'une
appli dépend d'abord de la qualité du programmeur. Et a mon avis un
bon programmeur java doit pouvoir déculotter un programmeur moyen en
C++.
Oui, c'est également ce que dit l'article : la variance est très

grande et le critère fondamental n'est pas le langage utilisé mais le
programmeur.

Globalement ta question est un peu vague, pour obtenir une bonne
réponse précise si tu souhaite te former à un des deux langages sans
but applicatif précis, ou si tu as une application (ou un domaine
d'application) en tête dis-nous laquelle, sans quoi tu n'auras pas de
réponse complète et pertinente à ta question.
Je voulais faire principalement deux choses (en ce moment), en dehors

de progresser en programmation (ce qui, par expérience, ne se fait
qu'en programmant)
Et en lisant (beaucoup), crois-moi tu ne trouveras jamais aussi vite

par expérience qu'en lisant, ou alors t'es un sacré génie....

: un administrateur d'IA pour un jeu, et des
algorithmes d'optimisation (toutes les méthodes utilisées en
math.app., du data minig AG-réseaux de neurones jusqu'à des méthodes
systématiques de recherche opérationnelle). Pour clarifier la première
partie, l'idée est de créer un programme qui reçoit le code de
sous-classes de la classe abstraite IA, et qui les fait jouer les unes
contre les autres pour les comparer. Bien sûr, de pair à ce projet, il
y a la programmation d'une de ces IA.
A priori tu n'auras pas besoin de portabilité, très peu besoin des API

supplémentaires fournies par Java, pas d'objet distribués... Après si
tu as besoin de perf (ce qui semble logique pour avoir des résultats
au plus vite) dans un contexte professionel je te conseillerais donc
C++... Mais si le but est aussi de te former à la prog, je te
conseillerais plutôt java. Java me semble plus pédagogique. Après,
quand tu seras un grand programmeur, tu pourras porter ton moteur d'IA
dans une librairie native C++ et optimiser pour tirer toute la
puissance possible de ta machine... Franchement tu peux le faire avec
l'un ou l'autre, vu que tu n'es pas un expert tu ne verras pas la
différence de perf avant d'avoir bcp lu et codé. Et quand tu seras un
expert, porter un tel code de java à C++ sera simple, le travail sera
négliegable en rapport de celui d'optimisation. Donc, fais un peu
comme tu as envie...


Avatar
vclassine
(Endymion) wrote in message news:...
wrote in message news:...

Surtout, si j'écris en C++ :

Objet o1 ;
Objet o2 = o1 ;

(Il y a aussi le fait que o1 est garanti d'être un objet valide. Pas de
pointeur null possible.)
Est-ce que ça veut dire que si la classe Objet est munie de la méthode

dyn. f(), alors o1.f() a toujours un sens ?


En premier lieu, évidemment, il consiste à définir un contrat pour la
classe et pour toutes ses fonctions. Un contrat qui précise ce que doit
faire la classe/fonction, et ce que doit faire l'utilisateur/appelant.
Ensuite, on aime ajouter des tests pour valider le contrat autant que
possible.
Est-ce qu'on peut dire que définir une classe abstraite avec quelques

méthodes abstraites et quelques champs et demader aux programmeurs
d'écrire des sous-classes de cette classe abstraite, c'est de la
programmation par contrat ?
Non c'est juste de l'héritage.

L'idée de la programmation par contrat c'est de garantir que le
contrat d'une méthode ou d'une classe sera respecté. Par exemple que
tel fonction ne peut pas être appellé si l'ojet est dans tel état, et
quand cette fonction est terminé l'objet doit être dans tel autre
état. Ou encore cette fonction ne peut pas être appelé avec un
argument négatif...

Après pour garantir le respect de ce contrat tu as des techniques
comme celles évoqués ailleurs dans le fil. L'utilisation de classes
abstraites conçue selon certaines rêgles est une de ces techniques...

Conclusion : il va falloir que je lise le livre conseillé ci-dessus

(de Meyer).
Et oui, et c'est plus une encyclopédie qu'une nouvelle...



Avatar
kanze
(Vincent) wrote in message
news:...
(Endymion) wrote in message
news:...
wrote in message
news:...
Ça dépend de ce qu'on veut faire. Si on a un style de
programmation résoluement OO, ils se ressemblent pour certaines
choses. Sinon : C++ permet d'autres idiomes aussi, ce qui n'est
pas le cas de Java.


Je ne sais pas ce qu'est le style OO. Du coup, je ne suis pas sûr de
connaître différents styles de programmation.

- En C++, on définit beaucoup de types avec une sémantique de
valeur : quand on déclare une variable de type T, c'est
réelement de la place d'un T qui est alloué par le compilateur
; il n'y a pas d'histoire de faire des new.


"Il n'y a pas d'histoire de new" : tu veux dire qu'on ne peut pas
caster un champ pour qu'il change de type ? ou que la création d'un
objet ne s'écrie pas par Objet o = new Objet(); ?


En fait "physiquement" il n'éxiste que des pointeur sur Objet en java.


Tu veux dire, ce qu'on déclare est un pointeur. Les objets existent
bien, quand même -- sinon, à quoi pointe le pointeur.

Concrètement en C++ tu peux écrire:
CString s;
ou
CString * ps;

En java, c'est:
String s;

Syntaxiquement ça ressemble à la première écriture, mais physiquement
ça correspond plus à la deuxième, c'est pour ça qu'en Java tu fais
systèmatiquement des new sur les objet. Par contre c'est l'inverse
pour les types primitif:
C++:
int i;
int * pi;

Java:
int i;

Là la syntaxe ne trouble pas, il s'agit de l'équivalent de la première
écriture en C++, par contre pour avoir "l'équivalent" de la seconde
écriture tu doit utiliser les classe Integer, Float...

- En C++, on utilise des destructeurs pour faire le menage. En
Java, les bloc de finally. La différence est, encore une fois,
fondamental. En C++, c'est la classe qui gère la ressource ou
la cohérence qui impose l'execution du nettoyage ; en Java,
c'est l'utilisateur de cette classe qui doit le faire
explicitement -- et je n'ai jamais vu un programme Java où il
n'en manquait pas de bloc de finally.


Ma question est hors sujet (je devrais la poser sur .lang.java) mais
comme tu en parles : qu'est-ce qu'un bloc finally ? (question qui
prouve que je programme sans faire le ménage comme tu le fais
remarquer ci-dessus)


try
{
//instructions à surveiller
}
finally
{
//instructions qui seront éxécutées quoiqu'il arrive (execptions ou
pas) lors de l'éxécution de des "instructions à surveiller".
}

En fait en java le garbage collector fait une bonne partie du boulot,
même si il est de bon goût de l'aider passer un certains niveau de
programmation. En fait les blocs try-finally sont nécessaires surtout
pour désallouer ce qui ne sera pas désallouer par le garbage collector
(notamment les ressources crées par une DLL native...)


La mémoire n'est pas le seul ménage qu'on fait, loin de là. Si c'est
vrai que bien plus de 90% des appels de destructeurs ne servent que pour
la mémoire, c'est toujoours le même code (pointeur intelligent, etc.).
En termes de quantité de code, je dirais que les problèmes de la gestion
de la mémoire n'est qu'une tout petite partie. (En passant, tu as oublié
qu'une autre utilisation fréquente des destructeurs en C++, c'est la
libération des mutex et d'autres rwlocks. Chose qui est réglée aussi par
le langage dane le cas de Java. Mais du coup, tu n'as pas accès aux
rwlock du tout.)

Et le ménage, ce n'est pas que « désallouer » quelque chose. C'est
retablir la cohérence de l'application. C'est l'integrité
transactionnelle, si tu veux.

- En C++, on distingue en général entre les erreurs à traiter
localement (indiquer par des valeurs de retour d'une
fonction), les erreurs à traiter globalement (les exceptions),
et les erreurs qui ne doivent en aucun cas se produire, et où
il faut avorter (les échecs d'assertion). Java traite tout par
des exceptions, ce qui le rend extrèmement difficile, sinon
impossible, à écrire un programme qui est réelement correct --
pour pouvoir se comporter d'une façon correcte lors d'une
exception, il faut qu'il y a certaines opérations qui ne
peuvent pas lever une exception. Or, en Java, même des chose
comme une erreur dans la machine virtuelle donne lieu à une
exception.


Je ne compremd pas l'importance de la différenciation : si tu mets
dans ton exception un catch{System.exit(0);}, le programme quitte
s'il rencontre cette erreur.


C'est encore un cas de programmation auquel tu n'as pas du être
confronter, d'ailleurs ça n'est pas mon domaine favoris non plus. En
gros je pense que l'idée c'est que le comportement des exceptions est
moins prévisible que celui du signalement d'erreur par code de retour.
Par conséquent ça pose des problèmes pour s'assurer de l'ordre
d'execution du code... Mais c'est juste une intuition Kanze pourra
mieux t'éclairer que moi.


Il y a beaucoup de choses qu'on entend sur le vocable « erreur ». Il y a
des erreurs dures du logiciels, voire même de hardware. Il y a des
erreurs assez sérieuses (manque de ressources, par exemple), qui le rend
impossible à finir la tâche en coure. Et il y a des erreurs
« attendues » : fichier non trouvé quand c'est l'utilisateur qui en a
précisé le nom. Essayer de les mettre toutes dans le même sac (comme
fait Java) ne marche pas.

Dans le cas des erreurs dures, il est prèsque toujours préférable
d'aborter toute de suite. Tu ne connais pas l'état de ton programme. En
essayant de remonter la pile, tu vas executer des destructeurs (C++) ou
des blocs finally (Java) ; en executant du code avec un état de
programme corrompu, tu risques de faire plus du mal que du bien.

Les cas où il faut aborter un traitement en cours, sans pour autant
aborter le programme complétement, sont les cas où l'exception brille.
C'est l'utilisation typique.

Les cas des erreurs attendues, en général, se traite mieux avec un code
de retour. Tu vas traiter l'erreur immediatement, sans rémonter la pile.
Alors, pourquoi la complexité des exceptions, si ça n'apporte rien.

La frontière entre les deux dernières est assez vague, et va dépendre en
partie de l'application, mais dans le cas des erreurs dures, générer une
exception est prèsque toujours incorrecte. Or qu'en Java, tu n'en as pas
le choix.

Juste une correction quand même, Java permet (dans ce domaine) la même
chose que C++. La différence c'est que l'api Java utilise plus
volontier les exceptions, mais rien n'oblige à faire de même dans son
propre code.


Au niveau du langage, tu as raison. En revanche, dans la bibliothèque,
c'est toujours de l'exception. Tu n'as pas le choix : si tu utilises des
assertions, tu as AssertionError (et non abort avec un message
d'erreur). Et tu crois vraiment qu'il y a des programmes qui vont
récupérer de VirtualMachineError.

En fait, le problème, c'est qu'il y a un mélange des concernes. À la
base, tu as Error et Exception, et sous Exception, tu as
RuntimeException. En général, ce qui est Error doit provoquer l'arrête
du processus, ce qui est RuntimeException aussi, dans beaucoup de cas,
mais c'est plus nuancé, et certaines applications doivent bien pouvoir
récupérer de certains RuntimeException. Et pour ce qui est d'Exception,
sans être un RuntimeException, il y a beaucoup de cas où un code de
retour conviendrait plus (mais là aussi, ça dépend de l'application).

- Java pose des problèmes pour la programmation par contrat. En
C++, c'est plutôt l'exception d'avoir une fonction virtuelle
publique -- la plupart en sont privée. En Java, on ne peut pas
déclarer une fonction privée virtuelle. Du coup, c'est
extrèmement difficile à forcer que tous les appels de la
fonction passent par une fonction non-virtuelle (final, en
Java) dans la classe de base ; fonction qui vérifie que le
contrat est maintenu.


Je suppose que la programmation par contrat consiste à créer une
classe abstraite avec des méthodes abstraites, ce qui force tous
ceux qui doivent créer des sous-classes de cette classe à définir un
certain nombre de méthodes.


Pas exactement l'idée c'est plutôt de s'assurer que le contrat de
chaque méthode soit respecter, par exemple qu'un argument de la
fonction n'est pas nul, ou que l'appel de telle fonction n'est
effectuée que dans une état donné de l'objet.

Mais là encore je ne suis pas tout à fait d'accord avec Kanze en fait
java permet tout à fait ce genre de chose. Pour les arguments et pour
une autre discussion sur C++ et Java (a propos de la qualité) voir le
fil "Pour ou contre un code 100% objet" sur fr.comp.objet.


Java permet à le faire, au moins en partie, à condition de renouncer à
l'héritage multiple. Dans l'application que j'ai fait en Java, on l'a
fait assez souvent quand même. Mais c'était parfois genant qu'une classe
ne pouvait pas implémenter plusieurs interfaces, simplement parce que
ces interfaces avaient un contrat, et qu'elles étaient donc implémentées
au moyen des classes abstraites, et non des interfaces du langage. (On
se démande, d'ailleur, pourquoi cette division arbitraire entre
« interface » et « class ».)

- Java, au moins dans les implémentations que je connais, impose
un certain dynamisme, qui n'est pas toujours souhaitable. En
C++, si tu veux, tu peux découper ton programme en objets
dynamiques (DLL's sous Windows, objets partagés sous Unix,
mais dans les deux cas, ce qui fait la différence, c'est que
l'édition de liens se fait lors de l'execution.) Or,
globalement, un objet dynamique n'est qu'une chose de plus que
tu ne contrôles pas complètement lors de l'execution. On les
évite autant que possible, à cause des erreurs qui en
proviennent.



C'est une approche très industrielle de la chose. Disons que selon les
domaines d'applications cette contrainte peut ne pas être pénalisante.


Ce qui est contraignant, c'est que tu n'as pas le choix, et que la
dynamisme se fait toujours avec la granularité d'une classe (ce qui est
bien petite). Il y a des domaines où un certain dynamisme est justifié.
Il est même souvent justifié pour une ou deux sous-systèmes. Jusqu'ici,
je n'ai jamais vu un cas où c'était justifié au niveau de la classe.

Il faut dire que même dans Java, il y a des hacks pour limité les
dégats. À quoi sert la possibilité de « seal » un fichier JAR, par
exemple, sinon qu'à limiter les effets du dynamisme. (Si tu avais la
possibilité de linker tout ce qu'il y avait dans le fichier en un seul
objet, comme c'est le cas avec C++ sous Windows ou sous Unix, tu
n'aurais pas besoin de cette fonctionnalité.)

Il n'y a donc pas d'équivalents Java des dlls ?


En fait en java tout ce comporte un peu comme des DLL dans la mesure
ou rien n'est vraiment "assemblé" en static. Mais je dirais que
l'équivalent des DLL (et des exe d'ailleurs) c'est les fichier JAR.


Sauf qu'il y a encore des problèmes avec CLASSPATH, et si le fichier JAR
n'a pas été scellé... (Et encore, le scellage ne fonction qu'au niveau
du package.) En somme, tes options sont très limitées, et le défaut
correspond en fait à quelque chose que tu ne voudrais jamais faire.

--
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
kanze
(Vincent) wrote in message
news:...
wrote in message
news:...
(Endymion) wrote in message
news:...

Vu d'un néophyte (pas débutant, mais pas très bon), quelles
différences y a-t-il entre Java et C++, mis à part quelques
petites particularités syntaxiques (syntaxe de création d'un
tableau, l'utilisation de destructeur d'objet, l'initialisation
par défaut des champs) ? Est-ce que l'héritage multiple change
vraiment quelque chose ?


Ça dépend de ce qu'on veut faire. Si on a un style de programmation
résoluement OO, ils se ressemblent pour certaines choses. Sinon :
C++ permet d'autres idiomes aussi, ce qui n'est pas le cas de Java.

La manque de l'héritage multiple gène parfois, mais dans l'ensemble,
c'est une différence mineur -- en C++, je l'utilise, mais pas dans
chaque hièrarchie non plus. Du point de vue de l'utilisateur, je
vois surtout les différences suivantes :

- En C++, on définit beaucoup de types avec une sémantique de
valeur : quand on déclare une variable de type T, c'est
réelement de la place d'un T qui est alloué par le compilateur ;
il n'y a pas d'histoire de faire des new. Pour les classes à
sémantique de valeur (comme une chaîne de caractères, des
complexes, etc.), c'est beaucoup plus simple (mais pas forcement
trivial non plus) à faire correctement en C++.

En Java, il faut déclarer la classe final, et s'assurer
qu'aucune fonction n'en modifie l'état (comme c'est le cas dans
java.lang.String). L'orientation de Java, c'est de privileger
les objets d'entité de l'application.

C'est probablement LA différence fondamentale. Elle est
pervasive. Même quand on utilise un style très OO, il s'avère
qu'environ la moitié des classes représentent des valeurs.


C'est une des différences fondamentales, mais pas forcément la plus
importante en pratique, ça dépends du domaine d'application...


Je ne crois pas. Dans tous les cas, tu as des types de valeur. Et dans
les deux langages, les idiomes pour implémenter les types de valeur sont
bien différents.

- Bien moins important (sauf quand tu en as besoin) : C++ a du
surcharge des opérateurs, qui permet à émuler un type de base.
C'est un épée à double tranchant -- c'est incroyablement facile
à en abuser (et comme en Java, la bibliothèque standard n'est
pas toujours un bon modèle). Mais supposons que pour des raisons
juridiques, tu sois obligé à tenir des valeurs monétaires en
décimal (c'est généralement le cas), est-ce mieux d'avoir à
écrire :
total = prixHorsTax + prixHorsTax * tva ;
comme en C++, ou :
total = prixHorsTax.add( prixHorsTax.mult( tva ) ) ;
comme en Java.


Vite dit:
total = prixHorsTaxe.applyTaxe(tva);
Est tout à fait acceptable et applyTaxe n'est guère plus long à écrire
que la surcharge de l'opérateur. Même si l'opérateur peut être employé
ailleurs...


Alors, il faut que tu introduit une classe supplémentaire -- une valeur
décimale qui connaît la TVA française.

Mais ce n'était qu'un exemple simple. Que faire dans les programmes du
marché, par exemple, où les formules qu'on manipule sont vraiment
compliqués, et qu'ils changent assez souvent. Que faire dans les
programmes scientifiques et techniques, ou on doit manipuler des
Complex -- le calcul d'impédence ne doit pas être évident.

Le problème est simple : quand tu as besoin du surcharge, tu en as
besoin, et il n'y a rien qui ne le remplace. Si tu travailles dans un
domaine technique, il y a de fortes chances que tu en auras besoin, au
moins pour Complex. Si tu fais de la comptabilité juridiquement valable,
tu en auras besoin, parce que la législation exige des arrondis sur la
base d'un calcul décimal.

En revanche, il y a effectivement beaucoup de domaines où tu n'en auras
pas besoin.

Comme tu le dis c'est à double tranchant, et ça n'est qu'une
fonctionnalité syntaxique qui en tout état de cause n'est pas souvent
vraiment utile.


Je n'ai pas dit que c'est souvent nécessaire. J'ai dit que quand c'est
nécessaire, les alternatifs sont vraiment moches.

En fait, dans ce cas-ci, Gosling est d'accord avec moi. Il veut ajouter
la surcharge d'opérateurs:-).

- Java, au moins dans ces premières versions, n'avait pas de
génériques. Ce qui limiter des prédicats sur le type que pouvait
enforcer le compilateur : en C++, si tu déclare un std::vector,
tu dis au compilateur le type que tu veux y mettre, et le
compilateur l'enforce. En Java, tu écris un commentaire qui dit
le type qu'il doit contenir, et en cas d'erreur, tu as une
exception à l'execution.


Là encore c'est une commodité syntaxique (qui sera incluse dans la
1.5) rien n'empêche d'écrire une version de chaque conteneur par type,
c'est lourd mais ça se fait.


En fait, rien n'empêche l'utilisation d'un préprocesseur. G++ le faisait
avant qu'il y avait des templates en C++, et ça marchait. Et la
simplicité du grammaire de Java doit en facilité l'écriture du
préprocesseur.

Ça, c'est en théorie. Pour une raison ou une autre, ce n'est pas ce qui
se fait en pratique (sauf quand moi, je fais du Java:-)).

- Java pose des problèmes pour la programmation par contrat. En
C++, c'est plutôt l'exception d'avoir une fonction virtuelle
publique -- la plupart en sont privée. En Java, on ne peut pas
déclarer une fonction privée virtuelle.


Euh? Privée virtuelle = protected (sauf que protected est accessible
aussi depuis le package, mais en principe on n'authorise personne de
non fiable à écrire dans son package).


Comment est-ce qu'on l'empêche, vue que le package est ouvert ?

(En fait, je crois que l'accessibilité « package », c'est la réponse de
Java au « friend » de C++. Ni l'un ni l'autre n'est totalement
satisfaisant. Mais pour que « package » soit une bonne réponse, il
faudra pouvoir fermer un package, et il faudrait supprimer l'accès
package aux classes dérivées en dehors du package. La possibilité de «
sceller » un fichier JAR s'adresse au premier problème, mais c'est un
hack, et pas du tout au bon endroit.)

Du coup, c'est extrèmement difficile à forcer que tous les
appels de la fonction passent par une fonction non-virtuelle
(final, en Java) dans la classe de base ; fonction qui vérifie
que le contrat est maintenu.


public abstract class AbstractTest
{
public final void faire_truc()
{
pre_condition();
faire_vraiment_truc();
post_condition();
}
private void pre_condition();
private void post_condition();

protected abstract void faire_vraiment_truc();
}


C'est ce que j'ai fait dans la pratique, mais la perte de l'héritage
multiple était genant dans certains cas.

- C++ permet la separation de l'implémentation et de l'interface.
En C++, c'est permis de définir des fonctions dans la définition
de la classe, comme on fait en Java, mais on constate très vite
que c'est une mauvaise idée. En Java, on n'a pas le choix. (Le
moyen qu'utilise C++ pour faire cette separation, l'inclusion
textuelle, est probablement le pire qu


En fait on peut très bien le faire en définissant une interface
pour chaque classe (ce qui n'est pas une mauvaise idée du reste),
c'est optionnel.


C'est optionnel en C++ aussi -- on *peut* écrire le C++ exactement comme
on écrit le Java. L'expérience a montré que c'est une très mauvaise
idée, et c'est interdit dans la plupart des régles de codage.

Quand a l'utilisation de l'interface, ça ne s'adresse que partiellement
au problème -- tu peux bien en déclarer des variables, mais tu ne peux
pas en créer des instances. Alors, du coup, il te faut une usine, et
beaucoup d'autres choses. C'est une solution assez lourde dans
l'ensemble.

Ce qu'il faudrait, idéalement, c'est des modules, comme en Ada. Mais une
fois de plus, la souplesse de C++ te permet à les simuler, plus ou
moins, et d'une façon vraiment pas très élégant, tandis qu'avec Java, tu
es coincé.

- Java, au moins dans les implémentations que je connais, impose
un certain dynamisme, qui n'est pas toujours souhaitable. En
C++, si tu veux, tu peux découper ton programme en objets
dynamiques (DLL's sous Windows, objets partagés sous Unix, mais
dans les deux cas, ce qui fait la différence, c'est que
l'édition de liens se fait lors de l'execution.) Or,
globalement, un objet dynamique n'est qu'une chose de plus que
tu ne contrôles pas complètement lors de l'execution. On les
évite autant que possible, à cause des erreurs qui en
proviennent.

En faveur de Java, évidemment, ce sont des bibliothèques standard
pour à peu près tout, et dans certains cas, comme les JSP,
l'environement applicatif.



Une autre chose en faveur, que j'avais oublié, c'est la qualité de la
documentation en ligne. Il n'y a rien en C++ qui ne s'approche de ce que
tu as à partir de http://developer.java.sun.com/developer/infodocs/.
(C'est un très fort argument pour l'utilisation de Java dans
l'enseignement, par exemple.)

Où puis-je trouver un document clair (français ou anglais) qui me
permette de faire la transition (j'ai lu un article disant que
C/C++ était plus rapide que Java et nécessitait moins de lignes) ?


Ça dépend de ce que tu fais. Il y a aussi des benchmark qui tournent
plus vite en Java qu'en C++. Dans la plupart des applications, en
revanche, j'imagine que le fait que C++ ait des véritables valeurs,
qu'on peut allouer sur la pile, ou mettre directement dans une
collection, fait que le C++ serait plus rapide.


Effectivement, mais ce gain de performance dépend de la qualité du
programmeur et n'est pas toujours nécessaire...


C'est même très rarement nécessaire, je dirais. Bien que... Quand j'ai
écrit l'application Java pour la Dresdner Bank, pour qu'elle tourne
correctement, il a fallu remplacer les PC sur lesquels elle tournait
avec des PC plus puissant. Or, même aux prix d'aujourd'hui, remplacer
60000 PC, ce n'est pas donné. (Mais je crois que le problème était
Swing, et non Java en soi.)

Plus important, pour des applications d'une certaine taille, je
trouve qu'on les développe plus rapidement en C++.


Je n'en suis pas convaincu, mais c'est normal ce genre de chose est
éminemment subjectif.


Ça se mésure. Je connais une ou deux boîtes qui l'ont mésuré. Le fait
est que pour un grand système :

- on dévelope plus rapidement en C++, et
- le résultat est nettement plus fiable en C++.

Pour des systèmes plus petits, c'est moins évident.

À la fin, tout dépend de l'application. Si je développais un site de
Web, je choisirais sûrement Java, à cause de tout l'environement autour.
Pour un logiciel client, j'aurais une tendance à préférer Java aussi, à
cause de Swing, et du modèle de deployement. Pour l'enseignement,
peut-être, à cause de la documentation et parce qu'il y a moins de
pièges bêtes (mais il y a tellement d'autres langages qui sont sans
doute supérieur aux deux). Pour d'autres choses, j'ai mes doutes.

--
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
(Vincent) wrote in message news:...

Et comment u fais en Java pour faire une classe qui "implémenteé deux
interfaces au snes donné par James (c'est-à-dire avec pre-conditions et
post-conditions) ? Sans héritage multiple d'implémentation, je ne vois pas
comment on pourrait s'en sortir.


Je comprend ce que tu veux dire, mais en fait en java la question se
pose différemment. Tu ne peux pas hérité de deux classe, donc pas de
deux classe "avec contrat". Quand tu hérites d'une classe tu as tous
les outils pour éviter la rupture du contrat. Si tu veux récupèrer
l'interface et le comportement de deux classes, tu dois:
- implémenter les deux interfaces. Ou une seule si tu hérites de
l'autre. Ou implémenter une interface qui hériterait des deux
autres...
- composer les deux classes portant le comportement, ou une seule
si tu hérit de l'autre, éventuellement en les dérivant.
- "brancher" les interfaces avec les classes membres.


Oui, mais avec toutes ces solutions alternatives, rien n'empêche
l'utilisateur de ta bibliothèque d'implémenter directement les 2
interfaces sans passer par ta/tes classe(s) qui "enforcent" le contrat
(c'est même la façon naturelle de faire en Java).

Arnaud


Avatar
kanze
(Vincent) wrote in message
news:...
(Endymion) wrote in message
news:...

Vu d'un néophyte (pas débutant, mais pas très bon), quelles
différences y a-t-il entre Java et C++, mis à part quelques petites
particularités syntaxiques (syntaxe de création d'un tableau,
l'utilisation de destructeur d'objet, l'initialisation par défaut
des champs) ?


C'est l'arbre qui cache la forêt, ces différences syntaxiques sont la
conséquence de différences de fond.

Est-ce que l'héritage multiple change vraiment quelque chose ?


D'abord en java tu peux faire de l'héritage multiple d'interfaces (une
interface peut hériter de plusieurs autres, et une classe peut
implémenter plus d'interfaces).


Une interface logique définit un contrat. Avec des invariants, des
préconditions et des postconditions. Qu'on ne peut pas vérifier dans une
interface Java.

Ce que tu ne peut pas faire c'est de l'héritage multiple de
comportement (une classe hérite de plusieurs).

A partir de là le fait que l'héritage multiple de classe soit interdit
rend pénible l'écriture de certains code, mais a aussi des avantages
de sécurité (d'ailleurs on pourrait dire qu'il en va de même pour
l'héritage simple de comportement).


Quel est l'avantage de sécurité ? Où plutôt, où sont les risques
associées à l'héritage multiple.

Mais ça ne concerne que les programmeurs objet avancés, les autres
font plus souvent des trucs dangereux avec... Si ça t'intéresse tu
peux jeter un coup d'oeil au fil "Pour ou contre un code 100% objet"
sur fr.comp.objet, il y a une discussion autour de ce sujet...

(j'ai lu un article disant que C/C++ était plus rapide que Java


Dans l'absolu, c'est vrai.


Pour beaucoup d'applications. Pas forcement pour toutes. Mais comme tu
dis, il y a bien peu d'applications où ça ferait une différence. Au
moins sous Windows, et à une moindre dégrée sous Solaris sur Sparc ;
beaucoup dépend de la qualité de la VM sur la plateforme, et sur la
plupart des plateformes, ce n'est pas terrible.

Et je ne parle pas des systèmes comme les Unisys 2200, où le hardware ne
supporte pas du tout le modèle imposé par Java. D'ailleurs, si tu vas
faire du virgule flottant, Java va ramer même sur un IBM 390 (qui ne
supporte pas IEEE très bien).

Si tu as besoin d'une vrai portabilité, il faut C++. Ou mieux, un
langage comme Ada, qui a une norme que les implémenteurs respectent,
mais qui peut s'implémenter sur n'importe quelle plateforme. (Mais dans
la pratique, c'est rare d'avoir besoin d'une telle portabilité.)

Pour la perf il ne faut pas se leurrer la vitesse d'éxécution d'une
appli dépend d'abord de la qualité du programmeur. Et a mon avis un
bon programmeur java doit pouvoir déculotter un programmeur moyen en
C++. Mais la première question à se poser, avant même de savoir si tu
vas pouvoir aller deux fois plus vite en C++, c'est est-ce que ton
besoin premier est la vitesse d'exécution...


La vitesse qui compte la plus, en général, c'est la vitesse de
développement. Et là, beaucoup dépend de l'environement. Si tu
développes, par exemple, un site Web, l'infrastructure et les
bibliothèques Java vont faire que tu as déjà 90% de fait ; C++ n'a pas
de chance. Si tu développes un gros serveur, en revanche, le modèle de
compilation de Java va te coûter environ 20% par rapport à celui de C++
(qui n'est déjà pas fameux). Si en plus, il faut que ce soit fiable, que
quand tu acquittes une requête, les données soient garanties sur disque,
alors, c'est infaisable en Java -- tu es obligé à passer par JNI, ce
qui, d'après le peu que j'ai vu, adopte les pires aspects des deux
côtés -- la légérté et l'élégance de l'écriture C++ avec la souplesse et
la vitesse de Java.

Si tu dois écrire une application de CAO 3D, java risque de te
bloquer.


Ce n'est pas dit. Si tu fais attention à ne travailler qu'avec les
double[], le résultat pourrait être même plus vite qu'avec C++. Sur
certaines plateformes, en tout cas -- la portabilité à ce niveau, ce
n'est pas le fort de Java.

Mais si tu dois juste écrire une appli de gestion le critère n'est
clairement pas la perf, sauf si tu dois utiliser des machines très
limitées...


Ou si c'est un programme très court, qui s'execute et puis s'arrête. Les
temps de démarrage de la machine virtuelle sont loins d'être
négligeable.

A mon avis c'est surtout la mémoire consommée qui est plus importante
en Java.


C'est un effet typique d'une ramasse-miettes. Tu me dirais que ça dépend
aussi ; si tu as une fuite de mémoire en C++, la mémoire consommée
risque d'être même plus qu'avec Java (au moins que tu as une fuite de
mémoire en Java, comme les premières versions de Swing).

Après la vitesse d'éxécution est souvent la même, même si il faut
reconnaitre que le temps de démarrage est alongé. Bien sûr ça dépend
de ton application...

De plus rien ne t'empêche de profiter des avantages de Java tout en
codant certaines parties coûteuses en C++...

et nécessitait moins de lignes) ?


Je répond pour la perf plus bas. Sur le nombre de ligne je peux déjà
te répondre que tous les programmes java et C++ peuvent s'écrirent sur
une seule ligne, ça n'est pas un critère.

Java demande un peu plus d'écriture à cause des try catch fréquents,
mais je dirais qu'un bon programmeur C++ les écrira (ou les
"if...else" qui les remplacent) partout où c'est obligatoire en Java,
donc match nul.


En général, en C++, on régle le problème avec les destructeurs. Ce qui
fait qu'il pourrait y avoir moins de code dans la plupart des cas. Dans
d'autres cas -- quand tu as des composants génériques (des collections,
etc.), en Java ou bien tu rénonces au typage statique (et donc prend une
risque supplémentaire des erreurs lors de l'execution), ou bien, tu as
des copies supplémentaire du code, qui ne varie que par le type. Mais
dans l'ensemble, je m'attendrais à un peu plus de lignes en C++. Parce
que tu fais plus -- tu vérifies les précondtions et les postconditions
(que tu ne peux pas faire en java), par exemple. Le resultat, c'est un
code plus robuste en C++.

Java est basé sur la même syntaxe que C++ donc pas de différence
significative... ça n'est pas comme en Delphi, Pascal, Ada, VB, ... où
tu écris:

if truc then
begin
.
.
.
end;
Là clairement il y a plus d'écriture, mais certains préfèrent...


[...]
En attendant tu peux toujours comparer la portabilité de Kylix,
wxWindows et Swing (voire même SWT). Ou comparer Eclipe et Netbeans
avec VisualStudio pour te faire une idée des possiblité graphique de
(respectivement) SWT et Swing, comparé aux MFC...


La portabilité est un épée à double tranchant. Si les cibles comprenent
des Unisys 2200, des IBM 390, etc., il n'y a que C++ (ou Fortran ou
Cobol -- je crois que même aujourd'hui, c'est Cobol qui est le plus
portable). Si tu te limites à des machines 32 bits, avec un virgule
flottant IEEE, sous Windows ou une variante de Unix, Java et C++ sont à
peu près aussi portable, avec la différence que tu as beaucoup moins à
faire attention à la portabilité en Java.

--
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
Gabriel Dos Reis
"Christophe Lephay" writes:

| "Gabriel Dos Reis" a écrit dans le message de
| news:
| > "Christophe Lephay" writes:
| >
| > [...]
| >
| > | Je crois que ce n'est pas demain la veille que C++ intègrera une GUI.
| C'est
| > | lié, de mon point de vue, au positionnement de C++ en ce qui concerne
| > | l'efficacité : standardiser quelque chose qui dépend autant de
| > | l'environnement ne peut se faire que par un nivellement par le bas (tant
| sur
| > | le plan des performances que du nombre de fonctionnalités).
| >
| > Ce n'est pas mon opinion. L'exemple de la STL n'est pas vraiment ce
| > que j'appelle un nivellement par le bas.
|
| Mais la SL me parait bien moins dépendant de l'environnement qu'une
| interface graphique...

C'est ce qu'on a essayé de faire croire. D'après toi quelle est la
définition de fichier ?

-- Gaby
Avatar
Gabriel Dos Reis
writes:

[...]

| > > Plus important, pour des applications d'une certaine taille, je
| > > trouve qu'on les développe plus rapidement en C++.
|
| > Je n'en suis pas convaincu, mais c'est normal ce genre de chose est
| > éminemment subjectif.
|
| Ça se mésure. Je connais une ou deux boîtes qui l'ont mésuré.

Je ne doute pas qu'ils aient fait des mesures ; la question
intéressante est qu'est-ce qu'ils ont réllement mesuré (et non ce
qu'ils ont prétendu mesurer), et quels sont les critères et les modes
opératoires ? :-)

-- Gaby
La numérologie est en passe de devenir une science
Avatar
Martinez Jerome
wrote:

La vitesse qui compte la plus, en général, c'est la vitesse de
développement.


Je suis du coté client.
Et ce qui m'interesse dans les contrats sont :
- les perfs : donc la vitesse d'execution : je t'embauche pour dire a
mes utilisateurs pour leur dire que si ils perdent la moité de leur
données temps réel a cause des perfs d'un appli, c'est pas grave...
- Le prix du developpement et la date de livraison, donc oui la vitesse
de developpement
Mais le deuxieme point est en deuxieme...

Ce n'est pas dit. Si tu fais attention à ne travailler qu'avec les
double[], le résultat pourrait être même plus vite qu'avec C++. Sur
certaines plateformes, en tout cas -- la portabilité à ce niveau, ce
n'est pas le fort de Java.


J'ai du mal a imaginer qu'un code précompilé soit plus rapide qu'un code
compilé, plus proche de la machine donc.
A optimisation egale (a la limite sans utiliser vector<>), le C++ serait
vraiment moins rapide que Java???
as-tu des exemples?
(j'avoue, c'est le principe meme de code non completement compilé plus
rapide que du code compilé qui me "choque". Mais bon, avec
l'informatique plus rien doit choquer... :) )