objective-C, C'est du C?
tablier
Membre
Objective-C, c'est du C! J'ai donc écrit le code ci-dessous:
Ce code sort presque directement du "Kernigham et richie". j'obtiens systématiquement l'erreur: "error: parse error before '=' token"
quelqu'un aurait une explication?
#import <Cocoa/Cocoa.h><br /><br /><br />@interface leControl : NSObject<br />{<br /> IBOutlet NSWindow *o_fenetre;<br /> IBOutlet NSMatrix *o_radio;<br /> IBOutlet NSButton *o_swich1;<br /> IBOutlet NSButton *o_switch2;<br /> IBOutlet NSTextField *o_texte;<br /><br /> struct le_champ {<br /> char *lenom ;<br /> int letype ;<br /> } DVDchamps[4] = { {"zero", 0}, {"un", 1}, {"deux", 2}, {"trois", 3} } ;<br />}<br />- (IBAction)a_annule:(id)sender;<br />- (IBAction)a_ok:(id)sender;<br />@end<br />
Ce code sort presque directement du "Kernigham et richie". j'obtiens systématiquement l'erreur: "error: parse error before '=' token"
quelqu'un aurait une explication?
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Je vais essayer autrement. Si non, ou puis-je lire des infos sur ce genre de difficultés?
En tout cas, bonne chance
Je confirme, ça fonctionne (en dehors de @interface/@end)
A+
Justement, c'est du C, c'est d'ailleurs pour ça que ce que tu as écrit ne fonctionne pas. Si tu testes en C pur (même C99) tu auras cette erreur. Pourquoi ?
Tout simplement parce que lorsque tu définis une structure en C, elle n'a pas d'existence dans la mémoire, on ne peut donc pas affecter des valeurs à ses champs lors de la déclaration. Essaye ceci en C :
Mon compilateur me renvoie une erreur similaire : error: syntax error before ‘=' token
En revanche, si tu écris :
C'est qu'en fait tu fais deux choses à la fois, tu fais d'abord la déclaration :
Suivit de la création d'une nouvelle variable :
Il est en revanche tout à fait possible dans les variables d'instance d'une classe de définir, comme en C dans une structure, de nouvelles structures et de donner un nom de champ :
Conclusion : l'erreur que tu trouves est une erreur tout à fait normale du point de vue de l'Objective-C comme du C.
et là , je n'ai plus d'erreur! Ce n'est pas la syntaxe qui est en cause, mais la place de la déclaration-initialisation. Plus exactement c'est l'initialisation directe entre { et } de l'@interface qui parait interdite.
Pour vérifier, j'ai écrit:
et l'erreur précitée réapparait!
Merci à tous et A+ :P
Mais, il s'agit d'une déclaration de structure, en C on ne peut pas faire d'affectation dans une déclaration de structure, alors dans une déclaration de classe on ne peut pas non plus le faire.
Ben oui.
On peut par artifice provoquer un comportement analogue.
Exemple : un compteur d'instances
De plus, rien ne t'empêches de définir ton compteur entre les directives @interface et @end de ta classe (après les accolades, puisque tu peux pas définir de variable d'instance statiques), il t'avertira que ta variable compteur n'est pas utilisé mais en fait elle le sera. Voire tu peux même les définir entre les directives @implementation et @end et en plus tu auras un warning de moins.
Le topic parle d'initialisation lors de la déclaration d'une classe. Cela ne peut avoir de vraie utilité que pour une variable qui serait partagée par toutes les instances, et non pas aux instances, sinon il n'y a qu'à le faire dans -(id)init.
Je présente ici une possibilité détournée de créer/initialiser/mettre à jour une telle variable partagée par toutes les instances.
En fait cette variable est une variable globale.Â
Certes. la place logique est extérieure à la zone "instance de classe".
Dans le .h entre @interface et @end, extérieur aux accolades, cela marche, mais je ne vois pas trop la signification.
Extérieurement cela me semble clair : c'est en quelque sorte rajoutée aux déclarations de la classe, visible par les instances.
Dans le .h,cela devrait être visible pour les autres classes après #import.
Dans le .m, c'est réservé aux instances.
Ceci dit si on prend un compteur de même nom pour deux classes différentes, sans avoir essayé, je pressens un conflit.
mon code est sans warning ( sauf le if(self=[super init]), mais c'est autre chose ).
J'ai fait l'essai, j'ai définit une classe dans le même fichier que le main, et une dans un fichier séparé, j'ai définit mes variables compteur comme étant static dans les .m et pas dans les .h, il n'y a aucun conflit entre elles.
Je ne parlais pas du tien. Si tu définis ta variable static dans l'interface de la classe, mais que tu ne l'utilises pas dans le même fichier, il te dira que la variable n'est pas utilité (warning), en revanche si tu la définis dans l'implémentation, le warning disparaà®t.
Normal qu'il n'y ait pas de conflit... C'est la même :P
Essaie de les utiliser, t'auras des surprisesÂ
PS : dans les .h non plus il n'y a pas de conflit...
Non non, j'ai fait le test, les valeurs changent indépendamment.
Parce que là :
"cpt" ne devrait rien avoir à voir avec "Class1"
C'est une variable statique qui est censée être globale partout, or là elle tient compte du scoping, c'est pas normal.
Donc c'est OK...
C'est de la bidouille pas très objet ça quand même
Quand une variable static est définie dans une fonction, elle est définie et initialisée qu'une seule fois, ensuite, lors des autres appels de la fonction, elle conserve la valeur qu'elle avait à la fin du précédent appel.
Lorsque la variable est définie dans un fichier qui n'est inclut nul par ailleurs, la variable en question est réservée au fichier dans lequel elle est définie.
Bah c'est-à -dire que les créateurs de l'Objective-C n'ont pas prévu de variable de classe tout simplement parce que le C avait déjà ce mécanisme, pa sla peine de le redéfinir, c'est vrai que c'est pas très propre, mais bon, pourquoi réinventer la roue ?
À mon avis ce système était plus simple à mettre en place que des variables de classe qui aurait obligé à créer des structures différentes pour chaque classe, alors que là on ne fait varier que les données que la structure de classe contient.
C'est un faux problème... Ils ont bien fait des méthodes de classe :P
Il n'y a pas énormément de différence entre les deux... C'est juste un pointeur à ajouter dans les structures.
Bah non justement, il n'est pas si faux que ça le problème. Les classes sont des structures prédéfinies dont voici l'ancienne apparence :
Le compilateur va simplement concevoir des instances de cette structures et en remplissant chaque champ avec les valeurs qu'il faut, c'est-à -dire la liste des variables d'instance (leur nom, leur type et leur place dans la structure), la liste des méthodes (sélecteur, types, adresse), et la liste des protocoles...
Je suis pas sûr que ça soit si facile d'ajouter des variables de classe... Quoique... à‰ventuellement, on pourrait ajouter un champ à cette structure contenant les adresses des variables de classe et leur type... Mais bon, encore faut-il y arriver.
Une variable statique a un comportement semblable à une variable globale au niveau de la durée de vie de l'information qu'elle porte.
Par contre au niveau de la visibilité, elle se comporte comme une variable automatique.
Dans le cas d'un source unique, et d'une définition comme on la dispose, c'est une variable globale.
c'est au niveau de la compilation que je craignais un conflit : genre "redéfinition d'une variable déjà existante". Mais en cas de compilation séparée, cela résout effectivement le problème.
D'ailleurs, les méthodes sont du même genre... C'est le même pointeur pour toutes les instances. (en C++ tout du moins, parce qu'en Objective-C, c'est un peu spécial)
En quel langage c'est un pointeur sur une variable ? Parce que jusqu'à nouvel ordre, ça n'existe pas en Objective-C. D'ailleurs je doute fortement que ce soit définit comme ça en C++ par exemple, ça utiliserait de la mémoire en plus pour stocker la valeur du pointeur de la variable de classe, ce n'est pas très économique, surtout pour pointé sur un unique élément bien définit. Et comme en C++, tout se passe à la compilation, le compilateur peut aisément retrouver la variable dans la mémoire.
En Objective-C, tous les objets ont dans leur variables d'instance un pointeur sur la structure représentant leur classe, et tous les pointeurs sur les méthodes sont stockés dans cette structure et cela permet de laisser au runtime le loisir de choisir la méthode à exécuter.
En C++, tout est définit à la compilation, donc à priori il n'y a pas besoin de stocker les pointeurs sur les méthodes, cela fonction comme les fonctions en C, le nom indique directement le code à exécuter. Il n'y a que pour les méthodes "virtual" qui fonctionnent différemment...
Quant à "virtual", ce n'est qu'une indication au compilateur pour dire que la méthode doit être implémentée dans les classes filles...
Quant*
Non, "virtual" indique que la méthode PEUT être redéfinie dans les sous-classes, et que donc il doit laisser le choix du code à exécuter à l'exécution. C'est lorsque la méthode est virtuelle pure qu'elle DOIT être redéfinie par les classes filles.
Sinon je suis pas vraiment d'accord sur le fait que ce ne soit pas plus dur d'implémenter une variable de classe que d'implémenter les méthodes de classe...
Pour les variables de classe, je ne pense pas que c'est pour la difficulté qu'ils ne l'ont pas mis, ou juste parce qu'il y avait déjà une méthode moins propre avec les static dans le .m...
C'est juste que c'est un concept pas très "objet", et qui ne sert que dans des cas très marginaux.
Le programmeur ne devrait pas avoir à "compter ses instances" dans un autre but que du debugging.
Quand on veut faire une variable de classe en C++ on utilise bien le mot clé "static", d'ailleurs il est fait pour ça :P
Et, de même, en C++, on déclare la variable de classe en "static" dans le ".h", et on l'initialise dans le ".cpp", d'ailleurs hors du code de la classe, comme on initialise une variable globale.
Alors en quoi ça vous pose souci ici ? Parce que c'est une static "de fichier" et pas "au sein d'une fonction ou d'une classe" ? Ben oui mais en même temps on est en C (enfin Obj-C) donc les classes de base ça n'existe pas en C... Alors c'est normal qu'on retombe dans ce mécanisme, non ?
Bon ok la déclaration du "static" pourrait être dans un @interface, mais l'initialisation dans le .m et hors du @implementation c'est comme en C++, non ?
Du coup ça suit la syntaxe du C tout en gardant les principes de codages du C++ (côté objet apporté par l'Objective-C)
Non, le problème c'est qu'il faut faire la déclaration dans le .m aussi !
Alors qu'en C++ on le fait dans le .h, c'est quand même plus logique...