Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

typedef et déclaration forward

4 réponses
Avatar
ALB
bonjour =E0 tous,

je cherche =E0 r=E9duire des d=E9pendances pour la compilation avec des
d=E9clarations forward de classes qui ne sont utilis=E9es que par pointeur/
r=E9f=E9rence dans les ent=EAtes.
Cependant, je rencontre un probl=E8me lorsque la classe d=E9clar=E9e est en
fait un alias (typedef).
Bref, comment faire pour limiter les d=E9pendances entre "classtypedef"
et "parent" dans l'esprit du cas simple ci-dessous (qui ne compile
pas) ?


fichier.h
-----------
class classtypedef;
struct parent {
int x;
parent(classtypedef& c);
};

fichier.cpp
---------------
#include "fichier.h"
typedef std::auto_ptr<int> classtypedef;
parent::parent(classtypedef& c)
: x (*c) {
};

4 réponses

Avatar
Fabien LE LEZ
On Mon, 20 Oct 2008 07:21:15 -0700 (PDT), ALB :

class classtypedef;



Ici, tu annonces un nouveau type.

Ça veut dire que le code ci-dessous devient légal :

void f (classtypedef x);
void f (std::auto_ptr<int> x);

typedef std::auto_ptr<int> classtypedef;



...et ici, tu annonces que finalement non, classtypedef n'est pas un
nouveau type.
Avatar
ALB
On 20 oct, 16:40, Fabien LE LEZ wrote:
On Mon, 20 Oct 2008 07:21:15 -0700 (PDT), ALB :

>class classtypedef;

Ici, tu annonces un nouveau type.

Ça veut dire que le code ci-dessous devient légal :

void f (classtypedef x);
void f (std::auto_ptr<int> x);

>typedef std::auto_ptr<int> classtypedef;

...et ici, tu annonces que finalement non, classtypedef n'est pas un
nouveau type.



Merci pour l'explication : j'avais bien remarqué que c'était interdit
sans trop voir pourquoi.
Ce que je cherche est une solution de contournement.
En pratique,
- int est remplacé par une classe (disons class model) et l'auto_ptr
est remplacé par un patron qui prend 4 paramètres.
- je ne trouve pas normal qu'une modification de model entraine la
recompilation de tous les utilisateurs de la 'class parent' (à cause
de l'include dans le .h)

J'ai bien pensé à faire une encapsulation de ce genre :
struct encapsulation {
patron<model, class1, class2, class3> model_;
};
et déclarer struct encapsulation;
et faire dépendre parent de encapsulation plutot que je classtypedef.
...mais je trouve cela un peu lourd à l'usage pour un problème sans
doute classique.
Avatar
Michel Decima
ALB a écrit :
On 20 oct, 16:40, Fabien LE LEZ wrote:
On Mon, 20 Oct 2008 07:21:15 -0700 (PDT), ALB :

class classtypedef;


Ici, tu annonces un nouveau type.

Ça veut dire que le code ci-dessous devient légal :

void f (classtypedef x);
void f (std::auto_ptr<int> x);

typedef std::auto_ptr<int> classtypedef;


...et ici, tu annonces que finalement non, classtypedef n'est pas un
nouveau type.



Merci pour l'explication : j'avais bien remarqué que c'était interdit
sans trop voir pourquoi.
Ce que je cherche est une solution de contournement.
En pratique,
- int est remplacé par une classe (disons class model) et l'auto_ptr
est remplacé par un patron qui prend 4 paramètres.
- je ne trouve pas normal qu'une modification de model entraine la
recompilation de tous les utilisateurs de la 'class parent' (à cause
de l'include dans le .h)

J'ai bien pensé à faire une encapsulation de ce genre :
struct encapsulation {
patron<model, class1, class2, class3> model_;
};
et déclarer struct encapsulation;
et faire dépendre parent de encapsulation plutot que je classtypedef.
...mais je trouve cela un peu lourd à l'usage pour un problème sans
doute classique.




Tu peux faire des 'forward declarations' des 4 classes, ainsi que
du patron, et definir le typedef dans un meme .h, comme ceci:

// forward.hh -------------------------------------------------------

class model ;
class class1 ;
class class2 ;
class class3 ;

template < class M, class C1, class C2, class C3 >
class patron ;

typedef patron< model, class1, class2, class3 > encapsulation ;

// f.hh -------------------------------------------------------

#include "forward.hh"

void f( encapsulation& e )

// f.cc -------------------------------------------------------

#include "f.hh"
#include "model.hh"
#include "class1.hh"
#include "class2.hh"
#include "class3.hh"

void f( encapsulation& e )
{
// ...
}

Le typedef 'encapsulation' est superflu, tu pourrais directement
utiliser patron< ... > dans la declaration de f(). Apres, en fonction
des besoins, tu peux repartir les forward-declarations dans plusieurs
fichiers (class1_forward.hh, etc).
Avatar
James Kanze
On Oct 20, 4:40 pm, Fabien LE LEZ wrote:
On Mon, 20 Oct 2008 07:21:15 -0700 (PDT), ALB :



>class classtypedef;



Ici, tu annonces un nouveau type.



Non seulement. Il dit aussi que c'est une classe. C'est très
importante, parce que le compilateur en a besoin pour gérer des
pointeurs.

Ça veut dire que le code ci-dessous devient légal :



void f (classtypedef x);
void f (std::auto_ptr<int> x);



>typedef std::auto_ptr<int> classtypedef;



...et ici, tu annonces que finalement non, classtypedef n'est
pas un nouveau type.



Et surtout, qu'il n'y a pas la classe promise.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34