C++/CLI Указатель на член

Каковы различные варианты реализации конструкции указатель на член в C++/CLI?

Я реализовал некоторые алгоритмы 2D геометрии, которые выполняют некоторые действия на основе координат X и Y. Я обнаружил, что я часто дублирую код один раз для оси X и один раз для оси Y. Примером является нахождение максимальных и минимальных границ по каждой оси.

Если бы я использовал собственный C++, я мог бы использовать указатель на член X или Y (также width, height и т. Д.) И передать его в качестве параметра, так что мне нужно реализовать каждый алгоритм только один раз. Но с C++ / CLI это невозможно. Какие у меня варианты? Я ищу что-то эффективное, легкое и лаконичное.

2 ответа

Решение

Вместо этого я бы сделал аргумент аргументом типа шаблона и использовал бы функторы, которые инкапсулируют доступ к свойству. Например:

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

Конечно, это имеет смысл, только если у вас достаточно много достаточно длинных алгоритмов, чтобы оправдать весь шаблон. Хотя обертки могут быть сгенерированы и доступны с помощью макроса, что существенно сокращает количество строк кода.

Вариант 1: если X и Y представлены как открытые члены, вы можете определить их как часть анонимного объединения, например:

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

Это позволяет вам обращаться к X как shape.X или shape.point[0], а так же shape.Y как shape.point[1].

Вариант 2: Если X и Y представлены как свойства, вы можете получить их геттеры / сеттеры для доступа к массиву элементов из двух элементов, а затем выставить массив как свойство только для чтения. Хотя вызывающая сторона не может изменить свойство массива, она все же может изменить свои элементы.

Вариант 3: ну, не вариант, правда. Не используйте.NET отражение для доступа к свойствам по имени. Стоимость выполнения слишком высока.

Другие вопросы по тегам