 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
PtitMat Guest
|
Posted: Wed Nov 17, 2004 6:58 pm Post subject: [Debutan C++] Retour pointeur |
|
|
Bonjour,
Je voudrais ecrire une fonction qui me retourne un pointeur vers une
variable.
Est-ce possible?
Je vous remercie pour votre aide
Mat.
|
|
| Back to top |
|
 |
Christophe Lephay Guest
|
Posted: Wed Nov 17, 2004 7:08 pm Post subject: Re: [Debutan C++] Retour pointeur |
|
|
PtitMat wrote:
| Quote: | Je voudrais ecrire une fonction qui me retourne un pointeur vers une
variable.
Est-ce possible?
Je vous remercie pour votre aide
|
C'est possible si la variable n'est pas locale :
// la variable existe en dehors de la fonction
int * fonction( int & variable )
{
return &variable;
}
Si c'est ta fonction qui la crée, sa durée de vie doit dépasser le stade de
la fonction et la variable ne peut donc plus être auto :
int * fonction()
{
int mal;
int * bon = new int;
// return &mal; // comme son nom l'indique
return bon; // c'est le code appelant qui devient responsable de la durée de
vie de la variable
}
Du point de vue du design, c'est souvent le signe d'une mauvaise conception
que de melanger variables (ou objets, dirons-nous) et pointeurs car celà
indique souvent qu'on gère pele-mêle différents niveaux d'abstractions.
Chris
|
|
| Back to top |
|
 |
Falk Tannhäuser Guest
|
Posted: Wed Nov 17, 2004 7:08 pm Post subject: Re: [Debutan C++] Retour pointeur |
|
|
PtitMat wrote:
| Quote: | Je voudrais ecrire une fonction qui me retourne un pointeur vers une
variable.
Est-ce possible?
|
Oui, tant qu'il ne s'agit pas d'une variable locale automatique.
Je ne sais pas si cela répond à ta question - qu'est-ce que tu
veux faire exactement ?
Falk
|
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Wed Nov 17, 2004 7:15 pm Post subject: Re: [Debutan C++] Retour pointeur |
|
|
On Wed, 17 Nov 2004 18:58:23 +0000, PtitMat <toto (AT) toto (DOT) fr>:
C'est possible (presque tout est possible en C++ ), mais pas
forcément une bonne idée.
--
;-)
|
|
| Back to top |
|
 |
PtitMat Guest
|
Posted: Wed Nov 17, 2004 7:23 pm Post subject: Re: [Debutan C++] Retour pointeur |
|
|
Christophe Lephay wrote:
| Quote: | PtitMat wrote:
Je voudrais ecrire une fonction qui me retourne un pointeur vers une
variable.
Est-ce possible?
Je vous remercie pour votre aide
C'est possible si la variable n'est pas locale :
// la variable existe en dehors de la fonction
int * fonction( int & variable )
{
return &variable;
}
Si c'est ta fonction qui la crée, sa durée de vie doit dépasser le stade de
la fonction et la variable ne peut donc plus être auto :
int * fonction()
{
int mal;
int * bon = new int;
// return &mal; // comme son nom l'indique
return bon; // c'est le code appelant qui devient responsable de la durée de
vie de la variable
}
Du point de vue du design, c'est souvent le signe d'une mauvaise conception
que de melanger variables (ou objets, dirons-nous) et pointeurs car celà
indique souvent qu'on gère pele-mêle différents niveaux d'abstractions.
Chris
Merci |
Une autre question plus de syntax :
Voici ma fonction écrite selon vos conseils :
int * Ccpu::dToR (int dx)
{
if (dx == 0)
{
return pR0;
}
if (dx == 1)
{
return pR1;
}
if (dx == 2)
{
return pR2;
}
if (dx == 3)
{
return pR3;
}
}
J'ai un warning a la compilation me disant que je ne retourn pas dans
tous les cas un element correct ce qui est vrai si dx vaut 4 par exemple
mais ce cas n'arivera pas : il y aura un control en amont avant
d'appeler la fonction.
Ma question est donc la suivant serait-il mieux d'enchainer les if dans
des else avec quelque chose du style
int * Ccpu::dToR (int dx)
{
if (dx == 0)
{
return pR0;
}
else
{
if (dx == 1)
{
return pR1;
}
else
{
if (dx == 2)
{
return pR2;
}
else
{
if (dx == 3)
{
return pR3;
}
}
}
}
}
|
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Wed Nov 17, 2004 7:39 pm Post subject: Re: [Debutan C++] Retour pointeur |
|
|
On Wed, 17 Nov 2004 19:23:16 +0000, PtitMat <toto (AT) toto (DOT) fr>:
| Quote: | J'ai un warning a la compilation me disant que je ne
retourn
|
Efforce-toi d'écrire toutes les lettres. Usenet != SMS.
| Quote: | pas dans
tous les cas un element correct ce qui est vrai si dx vaut 4 par exemple
mais ce cas n'arivera pas
|
Tu n'as aucun moyen d'en être sûr. Le mieux est de lancer une
exception en cas de paramètre incorrect.
| Quote: | Ma question est donc la suivant serait-il mieux d'enchainer les if dans
des else avec quelque chose du style
|
C'est illisible, donc forcément moins bien.
Mais bon, pourquoi faire compliqué ? Un switch conviendrait tout aussi
bien.
De plus, si ta fonction renvoie forcément un pointeur valide, autant
renvoyer une référence à la place :
int& Ccpu::dToR (int dx)
{
switch (dx)
{
case 0: return *pR0;
case 1: return *pR1;
case 2: return *pR2;
case 3: return *pR3;
default: throw std::domain_error
("Ccpu::dToR : paramètre invalide");
}
}
Mais bon, de toutes façons cette fonction devrait AMHA être inutile.
Tu as plusieurs pointeurs ayant presque le même nom ; un tableau
( std::vector<int*> ) conviendrait a priori bien mieux.
D'autre part, choisis des noms plus explicites !
"dToR" n'est pas un bon nom, car il n'indique pas au premier coup
d'oeil ce que fait la fonction. De même pour dx et pR0.
--
;-)
|
|
| Back to top |
|
 |
Christophe Lephay Guest
|
Posted: Wed Nov 17, 2004 7:52 pm Post subject: Re: [Debutan C++] Retour pointeur |
|
|
PtitMat wrote:
| Quote: | Une autre question plus de syntax :
Voici ma fonction écrite selon vos conseils :
int * Ccpu::dToR (int dx)
{
if (dx == 0)
{
return pR0;
}
if (dx == 1)
{
return pR1;
}
if (dx == 2)
{
return pR2;
}
if (dx == 3)
{
return pR3;
}
}
J'ai un warning a la compilation me disant que je ne retourn pas dans
tous les cas un element correct ce qui est vrai si dx vaut 4 par
exemple mais ce cas n'arivera pas : il y aura un control en amont
avant d'appeler la fonction.
|
Tu peux faire un switch...case et/ou :
int Ccou::dToR( int dx )
{
xxx * Pr;
switch( dx )
{
case 0: pR = pR0; break;
case 1: pR = pR1; break;
....
default: throw( "erreur" );
}
return pR;
}
Par ailleurs, il est bien possible que tu puisses mettre en oeuvre du
polymorphisme pour remplacer ces tests, mais c'est dur d'affirmer quoique ce
soit sans connaitre plus précisément ton problème :
- C'est quoi tes pR0...pRn ?
- Est-ce que ton objet peut à un moment donné avoir tous ces pRn
simultanément valides ? Ou un seul peut-il l'etre à la fois (auquel cas le
polymorphisme est plus approprié) ?
Chris
|
|
| Back to top |
|
 |
PtitMat Guest
|
Posted: Wed Nov 17, 2004 8:10 pm Post subject: Re: [Debutan C++] Retour pointeur |
|
|
Christophe Lephay wrote:
| Quote: | PtitMat wrote:
Une autre question plus de syntax :
Voici ma fonction écrite selon vos conseils :
int * Ccpu::dToR (int dx)
{
if (dx == 0)
{
return pR0;
}
if (dx == 1)
{
return pR1;
}
if (dx == 2)
{
return pR2;
}
if (dx == 3)
{
return pR3;
}
}
J'ai un warning a la compilation me disant que je ne retourn pas dans
tous les cas un element correct ce qui est vrai si dx vaut 4 par
exemple mais ce cas n'arivera pas : il y aura un control en amont
avant d'appeler la fonction.
Tu peux faire un switch...case et/ou :
int Ccou::dToR( int dx )
{
xxx * Pr;
switch( dx )
{
case 0: pR = pR0; break;
case 1: pR = pR1; break;
...
default: throw( "erreur" );
}
return pR;
}
Par ailleurs, il est bien possible que tu puisses mettre en oeuvre du
polymorphisme pour remplacer ces tests, mais c'est dur d'affirmer quoique ce
soit sans connaitre plus précisément ton problème :
- C'est quoi tes pR0...pRn ?
- Est-ce que ton objet peut à un moment donné avoir tous ces pRn
simultanément valides ? Ou un seul peut-il l'etre à la fois (auquel cas le
polymorphisme est plus approprié) ?
Chris
Ce qui se passe : |
J'ai un ordinateur composé d'une rom et d'un cpu
La rom est initialisé au début avec les instructions sous la forme d'un
tableau d'entier.
Une insrtuction a 3 chifres (341 ar exemple)
Le chifre numéro 1 appelé d1 (digit 1) indique le type d'opération
assembleur
Les chiffres 2 et 3 (d2 et d3) sont les opérandes.
Beaucoup de fonctions ont des operandes qui sont des numéros de
registres du CPU
Exemple move_value (value, Registre)
Ajoute(ValueRx, ValueRy)
Mes registres sont appelés R0 a R3
Ma fonction move_value (value, Registre)
appelle la fonction dToR pour convertir le digit qui lui est passé en
paramètre en pointeur vers le registre de manière a écrire la valeur dan
le bon registre.
J'ai pensé intelligent avec mon niveau de C++ de faire comme j'ai fait
mais 'est vrai qu'un swtch est plus propre.
De plus une gestion de l'erreur a se niveaux est sécuritaire, mais je ne
conaiisait pas cette commande :
default: throw( "erreur" );
Merci
Matthieu
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Wed Nov 17, 2004 8:14 pm Post subject: Re: [Debutan C++] Retour pointeur |
|
|
On Wed, 17 Nov 2004 20:10:50 +0000, PtitMat <toto (AT) toto (DOT) fr>:
| Quote: | conaiisait pas cette commande :
default: throw( "erreur" );
|
Jette-toi sur ton bouquin de C++, section "exceptions"...
--
;-)
|
|
| Back to top |
|
 |
Christophe Lephay Guest
|
Posted: Thu Nov 18, 2004 12:08 am Post subject: Re: [Debutan C++] Retour pointeur |
|
|
PtitMat wrote:
| Quote: | Ce qui se passe :
J'ai un ordinateur composé d'une rom et d'un cpu
La rom est initialisé au début avec les instructions sous la forme
d'un tableau d'entier.
Une insrtuction a 3 chifres (341 ar exemple)
Le chifre numéro 1 appelé d1 (digit 1) indique le type d'opération
assembleur
Les chiffres 2 et 3 (d2 et d3) sont les opérandes.
Beaucoup de fonctions ont des operandes qui sont des numéros de
registres du CPU
Exemple move_value (value, Registre)
Ajoute(ValueRx, ValueRy)
Mes registres sont appelés R0 a R3
Ma fonction move_value (value, Registre)
appelle la fonction dToR pour convertir le digit qui lui est passé en
paramètre en pointeur vers le registre de manière a écrire la valeur
dan le bon registre.
J'ai pensé intelligent avec mon niveau de C++ de faire comme j'ai fait
mais 'est vrai qu'un swtch est plus propre.
De plus une gestion de l'erreur a se niveaux est sécuritaire, mais je
ne conaiisait pas cette commande :
default: throw( "erreur" );
|
Le plus idiomatique serait de créer deux hiérarchies : une pour les
instructions, une autre pour les opérandes, puis une factory ("usine"
littéralement") qui te renverrait un pointeur sur un objet dérivé
instruction qui aurait lui-même extrait les opérandes de manière approprié.
Si tu débutes en C++, celà représente pas mal de choses à apprendre d'un
coup, mais tu bénéficierais de tous les avantages de la POO (en
l'occurrence, tu pourrais par la suite créer de nouvelles instructions sans
jamais avoir à changer le code qui aurait déjà été écrit, le rendant ainsi
facilement adaptable à d'autres CPUs).
En l'occurrence, la manière idiomatique de coder celà se ferait sans aucun
switch (une factory est généralement basée sur un tableau, éventuellement
associatif, de pointeurs de fonctions chargées chacune de construire des
objets d'un type spécifique). J'hésite à en dire plus à ce stade vu que tu
sembles débuter en C++. Si tu veux plus de détails, demande le en réponse à
ce post.
Chris
|
|
| Back to top |
|
 |
PtitMat Guest
|
Posted: Thu Nov 18, 2004 1:10 am Post subject: Re: [Debutan C++] Retour pointeur |
|
|
Christophe Lephay wrote:
| Quote: | PtitMat wrote:
Ce qui se passe :
J'ai un ordinateur composé d'une rom et d'un cpu
La rom est initialisé au début avec les instructions sous la forme
d'un tableau d'entier.
Une insrtuction a 3 chifres (341 ar exemple)
Le chifre numéro 1 appelé d1 (digit 1) indique le type d'opération
assembleur
Les chiffres 2 et 3 (d2 et d3) sont les opérandes.
Beaucoup de fonctions ont des operandes qui sont des numéros de
registres du CPU
Exemple move_value (value, Registre)
Ajoute(ValueRx, ValueRy)
Mes registres sont appelés R0 a R3
Ma fonction move_value (value, Registre)
appelle la fonction dToR pour convertir le digit qui lui est passé en
paramètre en pointeur vers le registre de manière a écrire la valeur
dan le bon registre.
J'ai pensé intelligent avec mon niveau de C++ de faire comme j'ai fait
mais 'est vrai qu'un swtch est plus propre.
De plus une gestion de l'erreur a se niveaux est sécuritaire, mais je
ne conaiisait pas cette commande :
default: throw( "erreur" );
Le plus idiomatique serait de créer deux hiérarchies : une pour les
instructions, une autre pour les opérandes, puis une factory ("usine"
littéralement") qui te renverrait un pointeur sur un objet dérivé
instruction qui aurait lui-même extrait les opérandes de manière approprié.
Si tu débutes en C++, celà représente pas mal de choses à apprendre d'un
coup, mais tu bénéficierais de tous les avantages de la POO (en
l'occurrence, tu pourrais par la suite créer de nouvelles instructions sans
jamais avoir à changer le code qui aurait déjà été écrit, le rendant ainsi
facilement adaptable à d'autres CPUs).
En l'occurrence, la manière idiomatique de coder celà se ferait sans aucun
switch (une factory est généralement basée sur un tableau, éventuellement
associatif, de pointeurs de fonctions chargées chacune de construire des
objets d'un type spécifique). J'hésite à en dire plus à ce stade vu que tu
sembles débuter en C++. Si tu veux plus de détails, demande le en réponse à
ce post.
Chris
Je commence par dejà apprendre a utiliser les exeptions avec les |
réponses précédentes.
Chaque chose en son temps.
La factory sera pour plus tard (je vai eviter de faire une usine a gaz
parfaite pour me perdre dans les vapeurs)... ;-)
Mat.
|
|
| Back to top |
|
 |
Christophe Lephay Guest
|
Posted: Thu Nov 18, 2004 2:05 am Post subject: Re: [Debutan C++] Retour pointeur |
|
|
PtitMat wrote:
| Quote: | Je commence par dejà apprendre a utiliser les exeptions avec les
réponses précédentes.
Chaque chose en son temps.
La factory sera pour plus tard (je vai eviter de faire une usine a gaz
parfaite pour me perdre dans les vapeurs)...
|
class instruction
{
....
virtual void extrait_operandes( std::istream& ) = 0;
public:
virtual ~instruction() {}
};
class ajoute : public instruction
{
char valeur;
reg registre;
void extrait_operandes( std::istream& is )
{
// extraire depuis le flux les opérandes requis
....
}
public:
// la fonction fabrique
static ajoute * make( std::istream& is )
{
ajoute * instr = new ajoute;
instr->extrait_operandes( is );
return instr;
}
};
classe soustrait : public instruction
{
char valeur;
reg registre;
void extrait_operandes( std::istream& is )
{
// extraire depuis le flux les opérandes requis
....
}
public:
// la fonction fabrique
static soustrait * make( std::istream& is )
{
soustrait * instr = new soustrait;
instr->extrait_operandes( is );
return instr;
}
};
Tu peux faire un fabrique sommaire basée sur un map :
typedef instruction * (* pf ) ( std::istream& ); // typedef pour pointeur
sur fonction
std::map< char, pf > fabrique;
// initialisation de la fabrique :
fabrique[ '1' ] = ajoute::&make;
fabrique[ '2' ] = soustrait::&make;
....
// disons que la rom est mappée dans le fichier "rom" :
std::ifstream ifs( "rom" );
// lecture du premier digit, code de l'instruction
char c;
ifs.get( c );
// recherche du digit
std::map< char, pf >::iterator it;
it = fabrique.find( c );
// erreur si l'instruction n'est pas reconnue par la fabrique
if( it == fabrique.end() )
throw( "instruction invalide" );
// dans le cas contraire, on appelle la fonction make associée via
déréférencement de l'itérateur
instruction * instr = (*it)( ifs ); // appel de la fonction make
....
En gros, ça te donne l'idée. Bonne digestion ;)
Chris
|
|
| Back to top |
|
 |
Pierre Maurette Guest
|
Posted: Thu Nov 18, 2004 8:26 am Post subject: Re: [Debutan C++] Retour pointeur |
|
|
PtitMat <toto (AT) toto (DOT) fr> a écrit:
[...]
| Quote: | Voici ma fonction écrite selon vos conseils :
int * Ccpu::dToR (int dx)
{
if (dx == 0)
{
return pR0;
}
if (dx == 1)
{
return pR1;
}
if (dx == 2)
{
return pR2;
}
if (dx == 3)
{
return pR3;
}
}
J'ai un warning a la compilation me disant que je ne retourn pas dans
tous les cas un element correct ce qui est vrai si dx vaut 4 par exemple
mais ce cas n'arivera pas : il y aura un control en amont avant
d'appeler la fonction.
(pour le warning, des réponses ont été données, c'est à vous de voir, |
selon la certitude que vous avez sur la valeur de dx)
Je verrais plutôt cette fonction renvoyer une référence qu'un
pointeur.
A la lecture des données de votre problème, il me semble qu'une
fonction n'est pas nécessaire, un tableau de pointeurs suffirait (je
crois qu'il n'est pas possible en C++ de faire directement un tableau
de reférences. J'ai bon ?)
Je vous propose un truc, étant entendu que je suis une buse en C++. Si
dx est une variable membre non static, il ne faut pas déclarer
Ccpu::dToR() en static.
<dans le Ccpu.h>
#if !defined(Ccpu_H)
#define Ccpu_H
extern int R0, R1, R2, R3;
class Ccpu
{
static int * dToRArray[4];
public:
Ccpu::Ccpu() { }
static int & dToR(int dx) { return * dToRArray[dx]; }
};
int * Ccpu::dToRArray[] = { &R0, &R1, &R2, &R3 };
#endif // Ccpu_H
<Test dans le main>
#include <iostream>
#include "Ccpu.h"
int R0, R1, R2, R3;
int main()
{
R0 = 12;
R1 = 45;
R2 = 88;
R3 = 9;
Ccpu* C = new Ccpu;
std::cout << Ccpu::dToR(0) << " / "
<< Ccpu::dToR(1) << " / "
<< Ccpu::dToR(2) << " / "
<< Ccpu::dToR(3) << std::endl;
Ccpu::dToR(1) = 12345;
std::cout << Ccpu::dToR(0) << " / "
<< Ccpu::dToR(1) << " / "
<< Ccpu::dToR(2) << " / "
<< Ccpu::dToR(3) << std::endl;
return EXIT_SUCCESS;
}
--
Pierre
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Thu Nov 18, 2004 10:01 am Post subject: Re: [Debutan C++] Retour pointeur |
|
|
Fabien LE LEZ <gramster (AT) gramster (DOT) com> wrote
| Quote: | On Wed, 17 Nov 2004 19:23:16 +0000, PtitMat <toto (AT) toto (DOT) fr>:
J'ai un warning a la compilation me disant que je ne retourn pas dans
tous les cas un element correct ce qui est vrai si dx vaut 4 par
exemple
mais ce cas n'arivera pas
|
C'est prendre tes souhaits pour la réalité .
| Quote: | Tu n'as aucun moyen d'en être sûr. Le mieux est de lancer une
exception en cas de paramètre incorrect.
|
Si la validité du paramètre est une précondition, une assertion vaut
mieux qu'une exception.
| Quote: | Ma question est donc la suivant serait-il mieux d'enchainer les if
dans des else avec quelque chose du style
C'est illisible, donc forcément moins bien.
Mais bon, pourquoi faire compliqué ? Un switch conviendrait tout aussi
bien. De plus, si ta fonction renvoie forcément un pointeur valide,
autant renvoyer une référence à la place :
int& Ccpu::dToR (int dx)
{
switch (dx)
{
case 0: return *pR0;
case 1: return *pR1;
case 2: return *pR2;
case 3: return *pR3;
default: throw std::domain_error
("Ccpu::dToR : paramètre invalide");
}
}
Mais bon, de toutes façons cette fonction devrait AMHA être inutile.
Tu as plusieurs pointeurs ayant presque le même nom ; un tableau (
std::vector<int*> ) conviendrait a priori bien mieux.
|
En fait, c'est un des cas où je me servirais d'un tableau à la C :
int&
Ccpu::dToR( int dx )
{
static int* const table[] =
{ &pR0, &pR1, &pR2, &pR3, } ;
assert( dx >= 0 && dx < sizeof( table ) /sizeof( table[ 0 ] ) ) ;
return *table[ dx ] ;
}
C'est la syntaxe de l'initialisation, ici, qui fait prévaloir T[] sur
vector
--
James Kanze GABI Software http://www.gabi-soft.fr
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
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|