2010-07-11 2 views
1

Если у меня есть простой класс, как это:C++ получить ключ массива в конструкторе массива пользовательского класса/структуры?

class MyClass 
{ 
    MyClass(){} 
    ~MyClass(){} 
public: 
    int myArrayKeyValue; 
}; 

И потом, я создаю массив этих классов:

MyClass testing[10]; 

Как, в конструкторе, я бы доступ к ключу массива, так что я может установить myArrayKeyValue соответственно для каждого элемента массива? Так что я получаю это:

testing[0].myArrayKeyValue = 0; 
testing[1].myArrayKeyValue = 1; 
testing[2].myArrayKeyValue = 2; 
testing[3].myArrayKeyValue = 3; 
etc... 

Можно ли выполнить это в конструкторе? Или мне нужно просто пропустить массив и назначить значения вручную?

ответ

3

Можно ли выполнить это в конструкторе?

No.

Или я должен просто цикл через массив и присвоить значения вручную?

Да. Хотя вы, возможно, сможете перепроектировать так, чтобы вам не нужно знание индекса внутри и за пределами этих случаев.

Возможные варианты включают:

  • ассоциативный контейнер, как map<int, MyClass>
  • set<MyClass> с ключевым значением является критериями, упорядочение
0

Вы не можете сделать это непосредственно из конструктора; он не имеет доступа к местоположению объекта в массиве. Вам нужно будет написать цикл для инициализации.

Альтернативно - и я чувствую себя немного отвратительно даже при упоминании об этом - используйте глобальный или статический счетчик, который вы увеличиваете от конструктора. Гарантируется, что порядок строительства начнется с начала массива до конца, так что это будет технически работать. Но это ужасно.

(Кстати, конструктор в вашем примере является частным, поэтому декларация массив не будет даже скомпилировать.)

0

Простой нуля static элемент, который увеличивается в конструкторе должен делать. Однако вам нужно сбросить его, прежде чем создавать массив. Является ли это хорошая идея, это совершенно другая тема :)

+2

Это рецепт катастрофы. Что делать, если вам нужно выполнить алгоритм в двух разных потоках одновременно? –

+0

Ну, не весь код заправлен. Но я не сказал, что это хорошая идея, не так ли? :) –

+0

Что делать, если он создает свою собственную ОС? Пожалуйста, не голосуйте за решения, адаптированные к предоставленной информации. Если бы он был многопоточным, он бы это уточнил. –

-1

Вы также можете использовать статический счетчик следующим образом:

class MyClass { 
    static size_t static_counter; 

    size_t m_value; 
public: 
    MyClass() { 
     m_value = static_counter++; 
    } 

    inline static void reset() { 
     static_counter = 0; 
    } 

    inline size_t get_value() const { 
     return m_value; 
    } 
}; 

size_t MyClass::static_counter = 0; 

Но вы должны Обязанностью сбросить вручную, или будет воспрещен памяти. Это будет исправлено путем инкапсуляции на более высоком уровне (сброс в деструкторе).

Редактировать: У меня была такая же идея, как Николай Н. Фетисов, и предвидеть: статические члены как таковые не должны использоваться в многопоточных программах.

+0

Голосов проголосовали? Вы, конечно, не поощряете других отвечать с проверенным кодом. –

+0

Этот тип статической инициализации не является хорошим решением. Да, это возможно, и это сработает, но именно по той причине, что вы упоминаете, что это плохо. –

+1

Плохо, только если программе суждено быть многопоточным, и, прежде всего, если мы не знаем, что делаем. Зачем голосовать за решение, которое ясно показывает его недостатки? Это зависит от создателя темы, чтобы выбрать ее, будь то моно или многопоточность. –

0

Нечто подобное можно было бы:

class MyClass { 
public: 
    MyClass(int index) { myArrayKeyValue = index; } 
    ~MyClass(); 
private: 
int myArrayKeyValue; 
}; 

int main() 
{ 
    MyClass testing[5] = { MyClass(1), MyClass (2), 
        MyClass (3), MyClass (4), MyClass (5) }; 

    return 0; 
} 
+0

Возможно, но явно не сгущается:/Вы можете писать (или копировать/вставлять) столько явных конструкций, сколько есть экземпляров? –

+0

Это зависит от того, хочет ли кто-то инициализировать массив объектов с различным значением, а не с помощью последовательности циклов. – cpx

0

Это может быть полезным рассмотреть то, что конечный результат вы хотите, и попытаться достичь ее с помощью других средств.

Один из способов, чтобы продолжить это может быть:

std::vector<MyClass> v; 
for (size_t i=0; i<nCount; i++) 
    v.push_back(MyClass(static_cast<int>(i))); 
+0

Это будет решение цикла (для меня лучше всего, но он, похоже, хочет метод построения), но в этом случае myArrayKeyValue должен быть непосредственно size_t, чтобы избежать static_cast, например, значение больше 2^15 (size_t эквивалентно к unsigned int). –