OVH Cloud OVH Cloud

Notation hongroise

22 réponses
Avatar
JBB
Y en a t'il parmi vous ( à part Microsoft) qui utilisent encore la
notation hongroise?

Rq: pour ceux qui connaissent pas ça consiste à faire des chose du genre:

class CMaClasse{

int m_iNombre;
long * m_plPointeur;

voif f()
{
char tcTexte[100];
}
};
au lieu de
class MaClasse{

int Nombre;
long * Pointeur;

voif f()
{
char Texte[100];
}
};

10 réponses

1 2 3
Avatar
JBB
Jean-Marc Bourguet wrote:
Fabien LE LEZ writes:

On 25 Oct 2005 11:55:35 +0200, Jean-Marc Bourguet :

La seule proposition que j'avais reellement a coeur de pouvoir faire
pour la prochaine revision de la norme etait un typedef introduisant
un nouveau type.
C'est vrai que ce serait très agréable...


Malheureusement, plus j'ai plonge dans les details
de la chose, moins ca m'a semble possible de maniere saine.
J'avais pensé à appliquer grosso modo les mêmes règles que pour

l'héritage (i.e. on "fait comme si" T hérite de U et U hérite de T),
mais j'avoue manquer de vision d'ensemble pour m'apercevoir de tous
les problèmes.


Un des objectifs d'un typedef fort est justement de ne pas pouvoir
utiliser un type pour l'autre.

A+

si je fait

typedef int taille_en_metre;
typedef int age;

j'aimerais bien que:
taille_en_metre longueur_du_bateau = 100;
age age_du_capitaine = 0;

age_du_capitaine = longueur_du_bateau; //error cast impossible

ne compile pas.

C'est ça de quoi vous parlez ?



Avatar
Jean-Marc Bourguet
JBB writes:

Jean-Marc Bourguet wrote:
Fabien LE LEZ writes:

On 25 Oct 2005 11:55:35 +0200, Jean-Marc Bourguet :

La seule proposition que j'avais reellement a coeur de pouvoir faire
pour la prochaine revision de la norme etait un typedef introduisant
un nouveau type.
C'est vrai que ce serait très agréable...


Malheureusement, plus j'ai plonge dans les details
de la chose, moins ca m'a semble possible de maniere saine.
J'avais pensé à appliquer grosso modo les mêmes règles que pour

l'héritage (i.e. on "fait comme si" T hérite de U et U hérite de T),
mais j'avoue manquer de vision d'ensemble pour m'apercevoir de tous
les problèmes.
Un des objectifs d'un typedef fort est justement de ne pas pouvoir

utiliser un type pour l'autre.
A+

si je fait

typedef int taille_en_metre;
typedef int age;

j'aimerais bien que:
taille_en_metre longueur_du_bateau = 100;
age age_du_capitaine = 0;

age_du_capitaine = longueur_du_bateau; //error cast impossible

ne compile pas.

C'est ça de quoi vous parlez ?


Oui. Et d'un tas de problemes annexes (parmi lesquel j'avais espere
pouvoir mettre une "forward declaration" pour les typedef).

int x;

age = x; // est-ce que ca doit etre possible?
x = age; // est-ce que ca doit etre possible?

age = age + 3; // possible? d'ou vient le +?
age = abs(age); // possible? d'ou vient abs?

int f(int);
age = f(age); // possible? comparer avec abs, c'est nettement moins desirable

int NS::f(int);
age = NS::f(age); // possible? encore moins desirable

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org




Avatar
Marc Boyer
Le 25-10-2005, JBB a écrit :
Jean-Marc Bourguet wrote:
Fabien LE LEZ writes:
Un des objectifs d'un typedef fort est justement de ne pas pouvoir
utiliser un type pour l'autre.

si je fait

typedef int taille_en_metre;
typedef int age;

j'aimerais bien que:
taille_en_metre longueur_du_bateau = 100;
age age_du_capitaine = 0;

age_du_capitaine = longueur_du_bateau; //error cast impossible

ne compile pas.

C'est ça de quoi vous parlez ?


Un truc comme celà oui.

Ce que j'arrive à faire pour le moment, c'est
du sous-typage.

class Integer{
// Un peu de code
};

#define SUBTYPE(NewType, Base) // Un peu de code

SUBTYPE(KiloOrange, Integer)
SUBTYPE(KiloPomme, Integer)

using std::cout;
using std::endl;

int main(){
Integer i(0);
KiloPomme p(0);
KiloOrange o(0);
i=0;
cout<<"i= "<<i<<endl;
cout<<"p= "<<p<<endl;
cout<<"o= "<<o<<endl;
cout<<"i+1= "<<i+1<<endl;

// Compile: bien
i=p;

// Compile pas: bien
o=p;

// Compile pas:bien
cout<<"p+o= "<<p+o<<endl;
}

Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangereux
que prendre un boulevard dans le sens légal. À qui la faute ?


Avatar
Marc Boyer
Le 25-10-2005, Jean-Marc Bourguet a écrit :
Oui. Et d'un tas de problemes annexes (parmi lesquel j'avais espere
pouvoir mettre une "forward declaration" pour les typedef).

int x;

age = x; // est-ce que ca doit etre possible?
x = age; // est-ce que ca doit etre possible?


Ces deux là me semblent du ressort de l'utilisateur,
non ?

age = age + 3; // possible? d'ou vient le +?


Ca, c'est horrible.

age = abs(age); // possible? d'ou vient abs?

int f(int);
age = f(age); // possible? comparer avec abs, c'est nettement moins desirable

int NS::f(int);
age = NS::f(age); // possible? encore moins desirable


Je vois pas bien pourquoi f et NS::f seraient différents ?
Tu as deux minutes pour m'expliquer ?

Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangereux
que prendre un boulevard dans le sens légal. À qui la faute ?

Avatar
Jean-Marc Bourguet
Marc Boyer writes:

Le 25-10-2005, Jean-Marc Bourguet a écrit :
Oui. Et d'un tas de problemes annexes (parmi lesquel j'avais espere
pouvoir mettre une "forward declaration" pour les typedef).

int x;

age = x; // est-ce que ca doit etre possible?
x = age; // est-ce que ca doit etre possible?


Ces deux là me semblent du ressort de l'utilisateur,
non ?


C'est une possibilite. J'aurais simplement tendance a accepter les
static_cast et puis c'est tout.

age = age + 3; // possible? d'ou vient le +?


Ca, c'est horrible.

age = abs(age); // possible? d'ou vient abs?

int f(int);
age = f(age); // possible? comparer avec abs, c'est nettement moins desirable

int NS::f(int);
age = NS::f(age); // possible? encore moins desirable


Je vois pas bien pourquoi f et NS::f seraient différents ?
Tu as deux minutes pour m'expliquer ?


Le probleme c'est que c'est difficile de rendre f different de abs
(sans compter qu'abs est aussi dans std...)

L'idee est que quand on cree un nouveau type en "copiant" un autre,
les operations de base sur ce type existent pour le nouveau. Le tout
est d'arriver a savoir ce que sont les operations de base; une idee
c'est ce qui est defini dans le meme namespace (c'est en gros la
logique de l'ADL) mais pour le namespace global ca peut etre beaucoup,
et quel est le namespace dans lequel sont definis les types de base?

package P is

type X is ...;
procedure F(An_X : X);

package S is
procedure G(An_X : X);
end S;
end P;


with P;
package P2 is
type Y is new X;
-- procedure F(An_X : Y) existe mais pas S.G().
end P2;

Pas sur d'avoir ete clair, mais j'ai pas le temps de faire mieux.

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Marc Boyer
Le 25-10-2005, Jean-Marc Bourguet a écrit :
Marc Boyer writes:
Le 25-10-2005, Jean-Marc Bourguet a écrit :
Oui. Et d'un tas de problemes annexes (parmi lesquel j'avais espere
pouvoir mettre une "forward declaration" pour les typedef).

int x;

age = x; // est-ce que ca doit etre possible?
x = age; // est-ce que ca doit etre possible?


Ces deux là me semblent du ressort de l'utilisateur,
non ?


C'est une possibilite. J'aurais simplement tendance a accepter les
static_cast et puis c'est tout.


En fait, c'est 'nouveau type' vs 'type dérivé'.
int x;
subtypedef int Age;
Age age;
x= age;
c'est la même chose que
class Mamifère {...}
class Chien: public Mamifère {...}
Chien c;
Mamifère m= c;

Disons que je pense que si on sait régler newtype, subtype
doit pas être beaucoup plus cher.

int f(int);
age = f(age); // possible? comparer avec abs, c'est nettement moins desirable

int NS::f(int);
age = NS::f(age); // possible? encore moins desirable


Je vois pas bien pourquoi f et NS::f seraient différents ?
Tu as deux minutes pour m'expliquer ?


Le probleme c'est que c'est difficile de rendre f different de abs
(sans compter qu'abs est aussi dans std...)


En effet.

L'idee est que quand on cree un nouveau type en "copiant" un autre,
les operations de base sur ce type existent pour le nouveau. Le tout
est d'arriver a savoir ce que sont les operations de base;


Oui.

une idee
c'est ce qui est defini dans le meme namespace (c'est en gros la
logique de l'ADL) mais pour le namespace global ca peut etre beaucoup,
et quel est le namespace dans lequel sont definis les types de base?

package P is

type X is ...;
procedure F(An_X : X);

package S is
procedure G(An_X : X);
end S;
end P;


with P;
package P2 is
type Y is new X;
-- procedure F(An_X : Y) existe mais pas S.G().
end P2;

Pas sur d'avoir ete clair, mais j'ai pas le temps de faire mieux.


Je crois que je comprends.

Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangereux
que prendre un boulevard dans le sens légal. À qui la faute ?



Avatar
Patrick 'Zener' Brunet
Bonjour.

Je réponds à JBB
Jean-Marc Bourguet wrote:
Fabien LE LEZ writes:

On 25 Oct 2005 11:55:35 +0200, Jean-Marc Bourguet :

La seule proposition que j'avais reellement a coeur de pouvoir
faire pour la prochaine revision de la norme etait un typedef
introduisant un nouveau type.
C'est vrai que ce serait très agréable...


Malheureusement, plus j'ai plonge dans les details
de la chose, moins ca m'a semble possible de maniere saine.
J'avais pensé à appliquer grosso modo les mêmes règles que pour

l'héritage (i.e. on "fait comme si" T hérite de U et U hérite de T),
mais j'avoue manquer de vision d'ensemble pour m'apercevoir de tous
les problèmes.


Un des objectifs d'un typedef fort est justement de ne pas pouvoir
utiliser un type pour l'autre.

A+

si je fait

typedef int taille_en_metre;
typedef int age;

j'aimerais bien que:
taille_en_metre longueur_du_bateau = 100;
age age_du_capitaine = 0;

age_du_capitaine = longueur_du_bateau; //error cast impossible

ne compile pas.



Pour l'assignation et la comparaison absolue (== ou !=) ça peut se faire,
mais pour d'autres opérations (+, -, etc. et aussi >, >= etc.), je ne crois
pas que ce soit possible...

Suite à de lourdes expériences, la seule solution que j'aie pu valider pour
créer des types incompatibles est la définition de types pointeurs:

typedef struct SDoNotUse1 { int _; } * HType1;

typedef struct SDoNotUse2 { int _; } * HType2;

... et donc on est sûr que HTypeN est compatible uniquement avec un autre
HTypeN.

Evidemment ça n'est pas opérable directement, ça sert à créer des types
Handle pour contenir des abstractions de données d'un type spécifique,
l'abstraction pouvant tenir sur une mantisse de pointeur (pointeur, entier,
bitfield, etc.).

Ce type de chose sert typiquement à permettre au code utilisateur (d'une
librairie) de garder au chaud l'abstraction et de la repasser en l'état aux
fonctions d'une API spécifique. Bref c'est un handle, une boîte noire.
D'ailleurs le FILE * des fonctions stdio est un handle qui s'ignore : qui a
déjà fait une indirection sur le FILE * pour manipuler la structure FILE ?

Et donc à l'intérieur des fonctions en question, on se réserve la compétence
pour décortiquer le contenu. Ca passe évidemment par des typecasts.

Au-delà, en C++, on peut aussi envisager de surcharger des opérateurs pour
qu'ils travaillent avec de tels handles (pour symboliser des opérations
(1)), à la restriction près qu'il faut qu'une classe soit impliquée dans
l'opération, ça ne marche pas avec les types atomiques. Mais par exemple
pour ajouter l'abstraction à une collection...

-----------------
(1) Tout ne se passe pas forcément dans la mémoire centrale, on peut opérer
symboliquement (donc par abstraction) sur des données qui sont effectivement
manipulées en conséquence au niveau d'un périphérique approprié.

Cordialement,

--
/***************************************
* Patrick BRUNET
* E-mail: lien sur http://zener131.free.fr/ContactMe
***************************************/




Avatar
Fabien LE LEZ
On Tue, 25 Oct 2005 13:32:35 +0200, JBB :

typedef int taille_en_metre;
typedef int age;

j'aimerais bien que:
taille_en_metre longueur_du_bateau = 100;
age age_du_capitaine = 0;

age_du_capitaine = longueur_du_bateau; //error cast impossible


Euh... J'ai dû rater quelque chose, car je ne vois pas bien l'utilité
de rajouter un truc dans le langage.


template <class T, class identifiant_unique>
class PseudoTypedef
{
public:
PseudoTypedef (T const& t= T());
// Ici, les fonctions dont tu as besoin -- ==, <, etc.
};

class BIDON_taille_en_metres {};
typedef PseudoTypedef <int, BIDON_taille_en_metres> taille_en_metres;

class BIDON_age {};
typedef PseudoTypedef <int, BIDON_age> age;

int main()
{
taille_en_metres longueur_du_bateau = 100;
age age_du_capitaine = 0;
age_du_capitaine = longueur_du_bateau; //error cast impossible
}

Avatar
Marc Boyer
Le 25-10-2005, Fabien LE LEZ a écrit :
On Tue, 25 Oct 2005 13:32:35 +0200, JBB :

typedef int taille_en_metre;
typedef int age;

j'aimerais bien que:
taille_en_metre longueur_du_bateau = 100;
age age_du_capitaine = 0;

age_du_capitaine = longueur_du_bateau; //error cast impossible


Euh... J'ai dû rater quelque chose, car je ne vois pas bien l'utilité
de rajouter un truc dans le langage.


Je crois que le problème, c'est 'obtenir *rapidement* une
nouvelle classe incompatible/peucompatible'.
Pour reprendre l'exemple de Joel, tu veux des 'safeString' et
'unsafeString', pour être sur de ne pas utiliser l'un pour l'autre.
Donc, à partir de std::string, en 3-4 lignes de codes, tu veux
safeString, unsafeString, tels que (à vue de nez):
- partout ou tu avais string tu peux utiliser safeString ou
unsafeString (pour récupérer tout l'existant)
- des règles de conversion unsafe -> safe mais pas
l'inverse.

Bon, là, ça se joue vite avec l'héritage.

Après, avec les types de base, ça devient plus pénible (mais
je note ton idée d'id unique, je n'y avais pas pensé).

Après, le besoin de Jean-Marc (il me semble) un nouveau
type, incompatible, qui récupère toutes les opérations.

Autant écrire le PseudoTypedef est envisageable pour
les types de base, autant pour un type utilisateur...

template <class T, class identifiant_unique>
class PseudoTypedef
{
public:
PseudoTypedef (T const& t= T());
// Ici, les fonctions dont tu as besoin -- ==, <, etc.
};

class BIDON_taille_en_metres {};
typedef PseudoTypedef <int, BIDON_taille_en_metres> taille_en_metres;

class BIDON_age {};
typedef PseudoTypedef <int, BIDON_age> age;

int main()
{
taille_en_metres longueur_du_bateau = 100;
age age_du_capitaine = 0;
age_du_capitaine = longueur_du_bateau; //error cast impossible
}



Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangereux
que prendre un boulevard dans le sens légal. À qui la faute ?


Avatar
Jean-Marc Bourguet
Marc Boyer writes:

Après, le besoin de Jean-Marc (il me semble) un nouveau type,
incompatible, qui récupère toutes les opérations.


Pas toutes justement. Le probleme est de definir une frontiere qui ne
soit pas trop restrictive (avoir un nouveau type pour lequel les
operateurs binaires non membres ne fonctionnent pas l'est
vraissemblablement) et pas trop large (sinon on n'a pas tellement
d'avantage a avoir un nouveau type).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

1 2 3