Отслеживание аргументов членов производного класса - PullRequest
0 голосов
/ 27 марта 2020

Допустим, у меня есть библиотека с виртуальным классом INode. Пользователь библиотеки может использовать INode для создания нескольких конкретных узлов (например, одного ConcreteNode) с любым видом функциональности, специализированным пользователем.

Прямо сейчас, если внутри какого-либо ConcreteNode я хочу объявить «специальный» скалярный аргумент, я вызываю метод arguments.scalar.add(0), ведьма создает мне новую запись внутри внутреннего вектора скалярных значений ( практически std::vector<double>) и начинает его с id = 0. Помимо именованного вектора чисел с именем scalar я также подготовил контейнеры с векторами (arguments.vector.) и матрицами (argument.matrix.) для вызова так же, как показано на рисунке.

Все это мотивировано мыслью, что я хочу отслеживать состояние (например, bool is_set;) для всех аргументов ConcreteNode. Это должно происходить «внутри», так что создателю ConcreteNode не нужно вручную отслеживать эти аргументы путем создания таких переменных состояния.

Мой текущий подход работает, но он ограничен предопределенными контейнерами (скаляр, вектор, матрица). Если используемая библиотека хотела использовать какой-либо другой тип данных, он должен добавить новую запись в класс INode. Вторая проблема заключается в том, что если я создаю ConcreteNode, ведьма использует только один скалярный аргумент, также создаются контейнеры для векторов и матриц. Это приводит к неработающему коду, ненужному использованию памяти, и наиболее важной частью является то, что я делаю запросы ко всем контейнерам, таким как bool arguments.are_set();, проверяющим все аргументы, даже если ни один из них не создан для вектора и матрицы.

Я ищу лучшее решение. Одна мысль заключалась в том, что если я перегрузлю оператор new внутри класса INode, то есть каждый вновь созданный аргумент любого типа внутри производного класса будет внутренне зарегистрирован таким образом, что ему дается несколько аргументов состояния и несколько стандартных наборов функций. /получить. Тогда код может быть очень гибким и, вероятно, выглядеть так:

struct ConcreteNode : INode
{
ConcreteNode() { bool* arg = new bool; }
void foo() override { /* ... use arg ... */ };
}

На этом этапе я спрашиваю себя, действительно ли необходим этот шаблон с new. Не могу ли я просто создать оболочку вокруг оператора new, чтобы он выглядел как обычная инициализация члена, например bool arg;. Или, может быть, я пропускаю какой-то хитрый трюк в cpp, который позволяет мне напрямую отслеживать созданных участников.

Надеюсь, я ясно изложил свои мысли, и вы могли бы помочь мне с ними go дальше ,

EDIT1: Я также думал о том, чтобы заставить некоторые структуры шаблонов вести себя как.

struct ConcreteNode : INode
{
ConcreteNode()
{  arguments.add<bool>("arg");
   arguments.set<bool>("arg") = true; }
void foo() override { /* ... bool b = arguments.get<bool>("arg"); ... */ };
}

EDIT2: Прямо сейчас, для текущего состояния кода я объявляю новые аргументы внутри производного класса, такие как это:

struct ConcreteNode : INode
{
ConcreteNode(double a, std::vector<double> b)
{  arguments.add.scalar(0);
   arguments.add.vector(1);

   arguments.set.scalar(0) = a;
   arguments.set.vector(1) = b;
 }
void foo() override 
{ 
   double c = arguments.get.scalar(0);
   std::vector<double> d = arguments.get.vector(1);
   // ...
};
}
...