OVH Cloud OVH Cloud

Declaration anticipee d'une sous classe

15 réponses
Avatar
Marc Boyer
Je n'arrive pas à faire une déclaration anticipée d'une
sous-classe. Voilà une version simplifiée du problème:
j'ai des Switchs, des Ports dans les Switch, et des
Flots qui traversent ces ports, de Switch en Switch.

Un Switch possède les flows qu'il émet. Un flow a une
liste de pointeurs sur les Ports qu'il traverse.


class Switch;
class Switch::Port; // error: no type named `Port' in `struct Switch'

class Flow {
std::list<Switch::Port*> path;
};

class Switch {
public:
class Port {
std::vector<Flow> send;
};
};

Et ça ne compile pas... Il y a bien sur plusieurs solutions:
un vecteur de Flow* dans un Port, ou ne pas faire de Port
une sous-classe de Switch, mais une classe à part.

Mais y a-t-il une autre solution ?

Marc Boyer
--
Entre le fort et le faible, c'est la liberte qui opprime et le droit
qui libere. Henri Lacordaire, Dominicain

10 réponses

1 2
Avatar
Franck Branjonneau
Marc Boyer écrivait:

Je n'arrive pas à faire une déclaration anticipée d'une
sous-classe.

class Switch;
class Switch::Port; // error: no type named `Port' in `struct Switch'


Donc,

class Switch {
public:


class Port;

};

class Flow {
std::list<Switch::Port*> path;
};


class Switch::Port {

std::vector<Flow> send;


};

--
Franck Branjonneau

Avatar
Marc Boyer
Le 15-02-2006, Franck Branjonneau a écrit :
Marc Boyer écrivait:

Je n'arrive pas à faire une déclaration anticipée d'une
sous-classe.

class Switch;
class Switch::Port; // error: no type named `Port' in `struct Switch'


Donc,

class Switch {
public:


class Port;

};

class Flow {
std::list<Switch::Port*> path;
};


class Switch::Port {

std::vector<Flow> send;


};


Je ne savais pas qu'on pouvait définir une sous-classe après l'avoir
déclaré. Ce qui est encore plus étonnant, c'est que je peux instancier
un vector de Port alors qu'il est juste déclaré mais pas définit...


#include <vector>

class Switch {
public:
class Port;
std::vector<Port> ports;
};

class Flow {
std::vector<Switch::Port*> path;
};

class Switch::Port {
std::vector<Flow> send;
};

Ce code compile chez moi (gcc 3.3.5).

Marc Boyer
--
Entre le fort et le faible, c'est la liberte qui opprime et le droit
qui libere. Henri Lacordaire, Dominicain


Avatar
Laurent Deniau
Marc Boyer wrote:
Je ne savais pas qu'on pouvait définir une sous-classe après l'avoir
déclaré. Ce qui est encore plus étonnant, c'est que je peux instancier
un vector de Port alors qu'il est juste déclaré mais pas définit...


#include <vector>

class Switch {
public:
class Port;
std::vector<Port> ports;
};


// Tu peux meme faire:

Switch var; // ici

class Flow {
std::vector<Switch::Port*> path;
};

class Switch::Port {
std::vector<Flow> send;
};

Ce code compile chez moi (gcc 3.3.5).


La difference entre translation units et instantiation units est
precisee dans 2.1-8. En fait l'instanciation de "Switch var" sera
consideree apres la definition de Switch::Port parce que la definition
de Switch implique un template (std::vector<>). Si tu remplace
std::vector<Port> ports par Port port; ca ne marche plus...

a+, ld.

Avatar
Franck Branjonneau
Marc Boyer écrivait:

Le 15-02-2006, Franck Branjonneau a écrit :

Je ne savais pas qu'on pouvait définir une sous-classe après l'avoir
déclaré. Ce qui est encore plus étonnant, c'est que je peux instancier
un vector de Port alors qu'il est juste déclaré mais pas définit...


Ce n'est pas portable : les composants de la bibliothèque
standard demande des types complets.

[Code]

Ce code compile chez moi (gcc 3.3.5).


Pas chez moi :

g++-4.0 -std=c++98 -W -Wall
-Wwrite-strings -pedantic-errors
-D_GLIBCXX_CONCEPT_CHECKS
-D_GLIBCXX_DEBUG
-D_GLIBCXX_DEBUG_PEDANTIC -c -o fclc++.o fclc++.cc

--
Franck

Avatar
Fabien LE LEZ
On Wed, 15 Feb 2006 15:22:49 +0000 (UTC), Marc Boyer
:

Ce qui est encore plus étonnant, c'est que je peux instancier
un vector de Port alors qu'il est juste déclaré mais pas définit...


Je ne sais plus trop si c'est garanti par la norme, même si ça l'est
pour std::list<>.

Avatar
Marc Boyer
Le 15-02-2006, Franck Branjonneau a écrit :
Marc Boyer écrivait:

Le 15-02-2006, Franck Branjonneau a écrit :

Je ne savais pas qu'on pouvait définir une sous-classe après l'avoir
déclaré. Ce qui est encore plus étonnant, c'est que je peux instancier
un vector de Port alors qu'il est juste déclaré mais pas définit...


Ce n'est pas portable : les composants de la bibliothèque
standard demande des types complets.


Merci de la précision.

[Code]

Ce code compile chez moi (gcc 3.3.5).


Pas chez moi :

g++-4.0 -std=c++98 -W -Wall
-Wwrite-strings -pedantic-errors
-D_GLIBCXX_CONCEPT_CHECKS
-D_GLIBCXX_DEBUG
-D_GLIBCXX_DEBUG_PEDANTIC -c -o fclc++.o fclc++.cc


Merci pour le test.

Marc Boyer
--
Entre le fort et le faible, c'est la liberte qui opprime et le droit
qui libere. Henri Lacordaire, Dominicain


Avatar
Marc Boyer
Le 15-02-2006, Laurent Deniau a écrit :
#include <vector>

class Switch {
public:
class Port;
std::vector<Port> ports;
};


// Tu peux meme faire:

Switch var; // ici

class Flow {
std::vector<Switch::Port*> path;
};

class Switch::Port {
std::vector<Flow> send;
};

Ce code compile chez moi (gcc 3.3.5).


La difference entre translation units et instantiation units est
precisee dans 2.1-8. En fait l'instanciation de "Switch var" sera
consideree apres la definition de Switch::Port parce que la definition
de Switch implique un template (std::vector<>). Si tu remplace
std::vector<Port> ports par Port port; ca ne marche plus...


Oulà...
Bon, j'avoue, dans le vrai code, j'ai laissé tombé ses subtilités,
j'ai plus de classe interne (en l'écrivant, je me dit que ce n'est
pas le bon mot), et j'ai mis des pointeurs partout.

Marc Boyer
--
Entre le fort et le faible, c'est la liberte qui opprime et le droit
qui libere. Henri Lacordaire, Dominicain


Avatar
Fabien LE LEZ
On Wed, 15 Feb 2006 17:08:43 +0100, Fabien LE LEZ
:

même si ça l'est
pour std::list<>.


À vrai dire, j'ai un gros doute. Quelqu'un peut confirmer/corriger ?

Avatar
Franck Branjonneau
Fabien LE LEZ écrivait:

On Wed, 15 Feb 2006 17:08:43 +0100, Fabien LE LEZ
:

même si ça l'est
pour std::list<>.


À vrai dire, j'ai un gros doute. Quelqu'un peut confirmer/corriger ?


J'infirme, lire autour de <news: ou
17.4.3.6.

--
Franck


Avatar
Fabien LE LEZ
J'ai écrit bêtement :

Je ne sais plus trop si c'est garanti par la norme, même si ça l'est
pour std::list<>.


En fait, j'ai confondu "type pas du tout défini" (i.e. un
forward-declaration uniquement) et "type en cours de définition" (i.e.
un std::list<C> membre de C).

Le code ci-dessous me semble correct :

class C
{
std::list<C> lc;
// ...
};

1 2