0 votes

C++/CLI Pointeur vers un membre

Quelles sont les différentes options pour implémenter une construction de type pointeur à membre en C++/CLI ?

J'ai implémenté quelques algorithmes de géométrie 2D qui effectuent certaines actions basées sur les coordonnées X et Y. Je constate que je duplique fréquemment le code une fois pour l'axe X et une fois pour l'axe Y. Un exemple est de trouver les limites maximales et minimales le long de chaque axe.

Si j'avais utilisé le C++ natif, j'aurais pu utiliser un pointeur sur le membre X ou Y (ainsi que sur la largeur, la hauteur, etc.) et le passer en paramètre afin de n'avoir à implémenter chaque algorithme qu'une seule fois. Mais avec C++/CLI, ce n'est pas possible. Quelles sont mes options ? Je cherche quelque chose d'efficace, de léger et de concis.

1voto

Oren Trutner Points 12125

Option 1 : si X et Y sont exposés en tant que membres publics, vous pouvez les définir comme faisant partie d'une union anonyme, par exemple

class Shape {
public:
    union {
        struct { double X; double Y; };
        double point[2];
    };
    ...
};

Cela vous permet d'accéder à X en tant que shape.X ou shape.point[0], et de la même manière, à shape.Y en tant que shape.point[1].

Option 2 : Si X et Y sont exposés en tant que propriétés, vous pouvez faire en sorte que leurs getters/setters accèdent à un tableau membre de deux éléments, puis exposer le tableau en tant que propriété en lecture seule également. Si l'appelant ne peut pas modifier la propriété du tableau, il peut néanmoins modifier ses éléments.

Option 3 : ce n'est pas vraiment une option. N'utilisez pas la réflexion .NET pour accéder aux propriétés par leur nom. Le coût d'exécution est beaucoup trop élevé.

1voto

Pavel Minaev Points 60647

Je ferais de l'argument un argument de type de modèle à la place, et j'utiliserais des foncteurs qui encapsulent l'accès aux propriétés. Par exemple :

ref class Point {
     property int X;
     property int Y;
};

struct Point_X_accessor
{
     static int get(Point^ p) { return p->X; }
     static int set(Point^ p, int value) { p->X = value; }
};

struct Point_Y_accessor
{
     static int get(Point^ p) { return p->Y; }
     static int set(Point^ p, int value) { p->Y = value; }
};

template <class PointAccessor>
int some_algorithm(Point^ p) { ... }

some_algorithm<Point_X_accessor>(p);
some_algorithm<Point_Y_accessor>(p);

Bien entendu, cela n'a de sens que si vous disposez d'un nombre suffisant d'algorithmes suffisamment longs pour justifier tout ce texte passe-partout. Les wrappers pourraient être à la fois générés et référencés via une macro, ce qui réduirait considérablement le nombre de lignes de code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X