Построить объект из нескольких источников, включая вектор объектов - PullRequest
0 голосов
/ 19 февраля 2020

Я получаю разные поля [потенциально одного класса] из двух разных источников на лету в c ++. Сначала поля класса A передаются в функцию # 1 (getData_Main), а затем вектор полей в другой локальной функции # 2 (getVecor_Sublass); Вызовы функций всегда последовательны # 1, а затем # 2. Вот упрощенные структуры данных:

class Subclass {
    string str;
    string str2;
    //a few other fields 
};

class Main {
    string name;
    float somevar;
    // few more string fields
    vector<Subclass> vecSubclass; 
};

Мне нужно сохранить состояние данных, чтобы сделать его постоянным для использования в других интерфейсах, что-то вроде построения vector<Main*> объекта-вектора. Я думал о создании переменной, которая служит в качестве индекса для основного класса и использовать тот же индекс в подклассе и сформировать своего рода таблицу поиска? Но как это сделать наилучшим и более эффективным способом?

К сожалению, я не очень хорошо знаком с современными функциями и конструкциями C ++ (11/14), все еще являюсь разработчиком C ++ 03), поэтому подумал о публикации здесь, чтобы получить некоторые предложения с некоторым рабочим фрагментом кода на случай, если лямбды или какие-либо более новые функции?

class Main 
{
    int index; //create from some static variable in function A and pass on to function B 
    string name;
    float somevar;
    vector<A> vecA;
};

Обновление (отвечая на комментарии)

Входные данные - поля данных , поступающие из java / jni нативные функции;

Требуемый вывод - это объекты vector<Main>.

Проблема # 1: поля ввода одного класса java входят в две собственные функции, поэтому C ++ получение двух наборов полей (Набор # 1 - это все поля Main класса, а набор # 2 - vector<Subclass>, содержащийся в полях класса Main;).

Я просто пытаюсь восстановить объект и пробую разные варианты.

Поскольку они входят в локальные функции, нет ничего общего в том, чтобы перестраивать vector объекты, если мы не делаем что-то вроде создания индекса, который будет служить ключом, и создания векторных объектов в C ++ из этих двух источников. Проблема № 2 - как это сделать наилучшим образом.

Надеюсь, теперь вопрос имеет какой-то смысл?

Отредактировано, чтобы добавить следующий Java код, который мы пытаемся имитировать c функциональность:

public class MainLine {
    String name;
    String Locator;
    Sub[] SubList = new Sub[5];
}
public class Test {
   MainLine[] MainLineArray = new MainLine[10000];
    // Data coming from some other sources in Java
   for (int j=0;j<10000;j++){
       test.addMainLine(MainLineArray[j].Locator, MainLineArray[j].name);
       for (int k=0;k<5;k++) {
        test.addSubList(MainLineArray[j].SubList[k].field1, MainLineArray[j].SubList[k].field2, MainLineArray[j].subList[k].field3,.....);
    }
  }
}

1 Ответ

0 голосов
/ 19 февраля 2020

Я думаю, вы спрашиваете, как создать объект, поля которого состоят из данных, полученных при множественных отдельных вызовах определенных функций. В общем, чтобы иметь дело с этими типами ситуаций, вам нужно передать идентификаторы или что-то в функции построения объектов, чтобы выяснить, какие значения принадлежат какому-либо объекту.

Но в случае JNI, как у вас, нативная функция может возвращать адрес как jlong, указывающий на незавершенный объект в процессе строительства, в программу Java, которая, в свою очередь, может многократно передаваться нативным функциям, обновляя тот же объект.

В Java:

native static long createMain(int val);

native static void addSubToMain(long main, int val);

void createMainsInNative() {
  long main = createMain("a");
  addSubToMain(main, "X");
  addSubToMain(main, "Y");
}

В C ++:

class Main {
  int val;
  std::vector<Sub> subs;
};

class Sub { int val; };

std::vector<std::unique_ptr<Main>> g_mains;

JNIEXPORT jlong Java_SomeClass_createMain(JEnv*, jclass, jint val)
{
  auto obj = std::make_unique<Main>();
  auto raw = static_cast<jlong>(reinterpret_cast<intptr_t>(obj.get()));
  obj->val = val;
  g_mains.emplace_back(std::move(obj));
  return raw
}

JNIEXPORT void Java_SomeClass_addSubToMain(JEnv*, jclass, jlong main, jint val)
{
  reinterpret_cast<Main*>(static_cast<intptr_t>(main))->subs.push_back(Sub { val });
}
...