2015-04-22 4 views
1

Мне нужно получить доступ к нескольким объектам класса под названием TH2D, который определяется программой корня (https://root.cern.ch/drupal/), с петлей для использования двух своих методов.объекты доступа в C++ по его имени

Название объектов находятся в виде run_0, run_1, run_2, и т.д ..

определяется следующим образом:

TH2F* run_0 = new TH2F("runID = 0", "projection during the first run", 
      COLUMN, -COLUMN_BOUND, COLUMN_BOUND, 
      RAW, -RAW_BOUND, RAW_BOUND); 

внутри для цикла для первого объекта я просто сделать:

int bin = run_0->FindBin(j, k); 
double Nphotons = run_0->GetBinContent(bin); 

Что мне нужно сделать, чтобы иметь что-то вроде этого внутри для цикла в C++ автоматически меняется run_0 к run_1 к run_2 и т.д ...?

первой итерации -

int bin = run_0->FindBin(j, k); 
double Nphotons = run_0->GetBinContent(bin); 

второй итерации -

int bin = run_1->FindBin(j, k); 
double Nphotons = run_1->GetBinContent(bin); 

РЕШИТЬ С:

TH2F* run[8]; 
run[0] = new TH2F("runID = 0", "projection during the first run", 
      COLUMN, -COLUMN_BOUND, COLUMN_BOUND, 
      RAW, -RAW_BOUND, RAW_BOUND); 

.... 

for(Int_t id = 0; id != 8; ++id) 
{ 
int bin = run[id]->FindBin(j, k); 
double Nphotons = run[id]->GetBinContent(bin); 
} 
+2

Поместите указатели на них в массив. Итерируйте массив. Предположим, что run_0, run_1, run_2 и т. Д. Либо уже находятся в коллекции, либо определены где-то. – Robinson

+0

Создаете ли вы эти объекты в своем собственном коде? Затем вы захотите поместить их (или указатели на них) непосредственно в контейнер вместо того, чтобы называть отдельные объекты. Если, otoh, объекты находятся в какой-либо библиотеке elses, вы все равно можете хранить указатели на них в контейнере, если вы должны проходить их более одного раза. Итерация/переплетение контейнеров тривиально. –

+0

я создал объекты в моем коде с: TH2F * run_0 = новый TH2F («RunID = 0, "проекция при первом запуске", \t \t \t COLUMN, -COLUMN_BOUND, COLUMN_BOUND, \t \t \t RAW, -RAW_BOUND, RAW_BOUND) например –

ответ

0

Предупреждение: Для простоты я буду считать маркеры в виде run_n являются функциями, а не объектами. Этот ответ также должен применяться к объектам.

Единственный способ поставить номер, как это в качестве идентификатора является макроподстановкам:

#define run(n) run_##n() 
run(0); // Good. Will expand to run_0(); 

К сожалению, это просто не работает с итерации:

#include <iostream> 

void run_0(){std::cout << 0;} 
void run_1(){std::cout << 1;} 

int main() { 
    for (int i=0;i<2;++i) { 
    run(i); // Bad. Will expand to run_i() and probably cause a compiler error. 
    } 
} 

И тогда вы есть проблема, что макросы не перебирают и не рекурсии. Если вы пишете это:

#define run(start,end) run(start,end-1) run_##end(); 

Это не будет расширяться в бесконечной рекурсии, так как кто-то мог бы догадаться. Вместо:

run(0,1); // Will expand to... 
run(0, 1-1) run_1(); // And stop expanding here. 

Поскольку ни функцииrun(), которая принимает два аргумента существует (Надеюсь, это не делает), то это вызовет ошибку компиляции.

Ваша единственная ставка, то оказывает список для всех возможных функций, а затем итерацию, что:

void (*run[10])() = {run_0, run_1, run_2, run_3, run_4, run_5, run_6, run_7, run_8, run_9}; 

int main() { 
    for (int i=0;i<10;++i) { 
    run[i](); // Now it works! 
    } 
} 

ответ на свой вопрос, то есть: Нет, это не возможно. Конечно, не так-оптимальные обходные пути, но, по сути, невозможно перебрать по группе идентификаторов по имени.

EDIT: Так как вы определяете объекты, и может позволить себе изменить, как определить их, это довольно просто:

PS: Так как вы «newing» объекты, я буду использовать новый. Предпочтительно, вы должны реализовать Rule of Three и распределить их статически или вместо этого использовать интеллектуальный указатель.

TH2F* run[10]; // Up to 10 objects. Probably better to use an std::vector instead. 
run[0] = new TH2F("runID = 0", "projection during the first run", COLUMN, -COLUMN_BOUND, COLUMN_BOUND, RAW, -RAW_BOUND, RAW_BOUND); 
run[1] = new TH2F("runID = 1", "projection during the second run", COLUMN, -COLUMN_BOUND, COLUMN_BOUND, RAW, -RAW_BOUND, RAW_BOUND); 

Затем вы можете перебирать этот массив и делать то, что вам нужно.

+0

Так что вы говорите, что я не могу делать то, что хочу автоматически? Постскриптум Я отредактировал свой вопрос, поэтому думаю, что вы можете лучше понять, что я хочу делать :) –

+0

Да, это не так. К сожалению, это невозможно. Для любого решения вам нужно будет перечислить все объекты где-нибудь. Если, конечно, ** вы ** не определяете объекты в форме 'run_n' и можете изменить это на более дружественный к итерации' run [n] '(т. Е.: Массив пробегов, а не несколько отдельных) –

+0

Хорошо, думаю, я понял. я определяю каждый объект, как это: 'TH2F * run_0 = новый TH2F ("RunID = 0", "проекция при первом запуске", \t \t \t COLUMN, -COLUMN_BOUND, COLUMN_BOUND, \t \t \t RAW , -RAW_BOUND, RAW_BOUND); \t \t TH2F * run_1 = новый TH2F ("RunID = 1", "проекция во время второго прогона", \t \t \t КОЛОННЫ, -COLUMN_BOUND, COLUMN_BOUND, \t \t \t RAW, -RAW_BOUND, RAW_BOUND); ' –

-2

В сущности, поместить их в массив:

Thingy * thing1 = new Thingy(); 
Thingy * thing2 = new Thingy(); 
std::vector<Thingy *> things; 
things.push_back(thing1); 
things.push_back(thing2); 
for(auto thing : things) 
{ 
    thing->doStuff(); 
} 

На самом деле подумайте об использовании интеллектуальных указателей, чтобы вы не забывали впоследствии их удалять.

Edit, потому что люди не нравится утечка:

std::shared_ptr<Thingy> thing1(new Thingy); 
std::shared_ptr<Thingy> thing2(new Thingy); 
std::vector<std::shared_ptr<Thingy> > things; 
things.push_back(thing1); 
things.push_back(thing2); 
for(auto thing : things) 
{ 
    thing->doStuff(); 
} 

и если вы действительно хотите:

std::vector<std::shared_ptr<Thingy> > things; 
for (int i = 0; i < count; ++i) 
{ 
    things->push_back(std::make_shared<Thingy>()); 
} 
for(auto & thing : things) 
{ 
    thing->doStuff(); 
} 
+0

Я думаю, что вопрос в том, можете ли вы сделать это без необходимости вручную перечислять объекты. Может быть, с ## оператором в макро или каким-либо другим способом. –

+1

Возможно, дополнительный пример смарт-указателя в порядке. – tweej

+2

Почему утечка памяти? – juanchopanza

Смежные вопросы