Указатель C++/CLI на член
-
13-09-2019 - |
Вопрос
Каковы различные варианты реализации конструкции указателя на член в C++/CLI?
Я реализовал несколько алгоритмов двумерной геометрии, которые выполняют некоторые действия на основе координат X и Y.Я обнаружил, что часто дублирую код один раз для оси X и один раз для оси Y.Примером может служить поиск максимальных и минимальных границ вдоль каждой оси.
Если бы я использовал собственный C++, я мог бы использовать указатель на элемент X или Y (а также ширину, высоту и т. д.) и передать его в качестве параметра, чтобы мне нужно было реализовать каждый алгоритм только один раз.Но с C++/CLI это невозможно.Какие у меня есть варианты?Я ищу что-то эффективное, легкое и лаконичное.
Решение
Вместо этого я бы сделал аргумент аргументом типа шаблона и использовал функторы, инкапсулирующие доступ к свойствам.Например.:
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 для доступа к свойствам по имени.Стоимость выполнения слишком высока.