OVH Cloud OVH Cloud

Constructeur et paramètres optionels

9 réponses
Avatar
Fabien SK
Bonjour,

Dans une classe je voudrais avoir constructeur avec des paramètres
optionnels, comme:

class Toto
{
public:
Toto(int id1=-1, int id2=-1);
};

Le problème est que je peux avoir toutes les combinaisons de "id1" et
"id2" (les deux, aucun, seulement l'un d'eux). Comme les paramètres sont
du même type, je ne peux pas faire différents constructeurs.

Sinon, je pourrais faire:

class Toto
{
public:
Toto(int id1, int id2);
static Toto* FromId1(int id1);
static Toto* FromId2(int id2);
};

Note: "Toto" ne va pas être alloué sur la pile alors je peux retourner
un objet sur le tas.
Mais ma syntaxe n'est plus uniforme.

Peut-être avez-vous une solution miracle et élégante pour ce genre de
problème.

Merci de votre attention

9 réponses

Avatar
Jean-Marc Bourguet
Fabien SK <fabsk+ writes:

class Toto
{
public:
Toto(int id1=-1, int id2=-1);
};

Le problème est que je peux avoir toutes les combinaisons de "id1" et "id2"
(les deux, aucun, seulement l'un d'eux). Comme les paramètres sont du même
type, je ne peux pas faire différents constructeurs.


Et comment veux-tu faire la difference entre seulement le premier et
seulement le deuxieme?

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
Fabien SK
Jean-Marc Bourguet wrote:

class Toto
{
public:
Toto(int id1=-1, int id2=-1);
};

Le problème est que je peux avoir toutes les combinaisons de "id1" et "id2"
(les deux, aucun, seulement l'un d'eux). Comme les paramètres sont du même
type, je ne peux pas faire différents constructeurs.



Et comment veux-tu faire la difference entre seulement le premier et
seulement le deuxieme?


C'est justement le problème, et pourquoi le prototype ci-dessus ne me
convient pas. Je sens que le seul moyen est de faire des méthodes
statiques...


Avatar
Christophe Lephay
Fabien SK wrote:
Jean-Marc Bourguet wrote:

class Toto
{
public:
Toto(int id1=-1, int id2=-1);
};

Le problème est que je peux avoir toutes les combinaisons de "id1"
et "id2" (les deux, aucun, seulement l'un d'eux). Comme les
paramètres sont du même type, je ne peux pas faire différents
constructeurs.



Et comment veux-tu faire la difference entre seulement le premier et
seulement le deuxieme?


C'est justement le problème, et pourquoi le prototype ci-dessus ne me
convient pas. Je sens que le seul moyen est de faire des méthodes
statiques...


Un autre en est de créer des types distincts pour id1 et id2...

struct primary_key {
primary_key( int some_key ) : key( some_key ) {}
int key;
};

struct foreign_key {
foreign_key( int some_key ) : key( some_key ) {}
int key;
};

class toto
{
public:
toto( primary_key id1, foreign_key id2 = -1 );
toto( foreign_key id2, primary_key id1 = -1 );
};

Mais bon, si l'idée des valeurs par défaut est de t'éviter d'avoir à taper
quelque chose, je crains que le remède ne soit pire que le mal :)

A mon avis, des valeurs par défaut ne sont tout simplement pas adaptées à
ton cas...

Chris

Chris



Avatar
Marc Boyer
Fabien SK wrote:
Bonjour,
Dans une classe je voudrais avoir constructeur avec des paramètres
optionnels, comme:

class Toto
{
public:
Toto(int id1=-1, int id2=-1);
};

Le problème est que je peux avoir toutes les combinaisons de "id1" et
"id2" (les deux, aucun, seulement l'un d'eux). Comme les paramètres sont
du même type, je ne peux pas faire différents constructeurs.


Si c'est juste pour deux, pas la peine de sortir le marteau pilon.
Si c'est pour une très longue liste, tu peux passer par un objet
intermédiaire, genre Toto::Toto_args pour construire
Toto toto(Toto_args.setOptSize(50)
.setOptDepth(125));

C'est expliqué dans le DnE. Je manque de temps là,
mais si tu es intéressé, je t'explique plus en détails
demain.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

Avatar
Vincent Lascaux
class Toto
{
public:
Toto(int id1=-1, int id2=-1);
};


Une autre idée qui me vient à l'esprit (apres tout ce qui a été dit) :

class Toto
{
public:
struct FromID1 { };
struct FromID2 { };
Toto(int id1, int id2);
Toto(FromID1, int id1);
Toto(FromID2, int id2);
Toto();
};

Ensuite on peut faire

Toto t1(Toto::FromID1(), 2);
Toto t2(Toto::FromID2(), 1);

Je trouve ca assez elegant...

Avatar
Fabien SK
On Mon, 17 Nov 2003 17:26:03 +0000, Marc Boyer wrote:

Si c'est juste pour deux, pas la peine de sortir le marteau pilon.
Si c'est pour une très longue liste, tu peux passer par un objet
intermédiaire, genre Toto::Toto_args pour construire
Toto toto(Toto_args.setOptSize(50)
.setOptDepth(125));

C'est expliqué dans le DnE. Je manque de temps là,
mais si tu es intéressé, je t'explique plus en détails
demain.


Pas besoin de plus de détail, j'ai compris. Bon ce ne sera pas pour cette
fois, mais c'est intéressant. Merci

Avatar
Fabien SK
On Mon, 17 Nov 2003 19:04:52 +0100, Vincent Lascaux wrote:

Ensuite on peut faire

Toto t1(Toto::FromID1(), 2);
Toto t2(Toto::FromID2(), 1);

Je trouve ca assez elegant...


Effectivement, c'est chouette. Malheureusement, ce pan de projet a été
supprimé, donc plus de problème :-) Mais bon, ce n'était pas pour rien.
Merci

Avatar
Fabien LE LEZ
On Mon, 17 Nov 2003 19:04:52 +0100, "Vincent Lascaux"
wrote:

class Toto
{
public:
struct FromID1 { };
struct FromID2 { };
Toto(int id1, int id2);
Toto(FromID1, int id1);


Sympathique effectivement :-)


--
;-)

Avatar
kanze
"Vincent Lascaux" wrote in message
news:<3fb90dbf$0$13304$...

class Toto
{
public:
Toto(int id1=-1, int id2=-1);
};


Une autre idée qui me vient à l'esprit (apres tout ce qui a été dit) :

class Toto
{
public:
struct FromID1 { };
struct FromID2 { };
Toto(int id1, int id2);
Toto(FromID1, int id1);
Toto(FromID2, int id2);
Toto();
};

Ensuite on peut faire

Toto t1(Toto::FromID1(), 2);
Toto t2(Toto::FromID2(), 1);

Je trouve ca assez elegant...


Dans ce cas-là, je préfère des enum :

class Toto
{
public :
enum Id1 { id1 } ;
enum Id2 { id2 } ;
Toto( int id1, int id2 ) ;
Toto( Id1, int id1 ) ;
Toto( Id2, int id2 ) ;
// ...
} ;

Toto t1( Toto::id1, 2 ) ;
Toto t2( Toto::id2, 1 ) ;

etc. (Il y a un example dans mon GB_BenchHarness, à ma site, par
exemple. La technique est assez ancienne. On s'en servait aussi pour
faire ce que fait explicit, avant qu'il y avait explicit.)

--
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