2016-10-25 3 views
1

Я пытаюсь получить отличное значение из моего перечисления с помощью указателей void.Получение различных значений перечисления C++

Я перечисление декларации списка животных

enum Animal {Rat, Ox, Tiger, Rabbit, Dragon, Snake, Horse, Sheep, Monkey, Rooster, Dog, Pig}; 

Итак, во-первых, у меня есть функция, которая возвращает меня значение из моего перечисления случайно

VoidPtr getAnAnimal() 
{ 
    VoidPtr anAnimal; 

    Animal *a = new Animal; 

    int k = rand() % 12; 

    *a = static_cast<Animal>(k); 

    anAnimal = a; 

    return anAnimal; 
} 

Тогда во время моего строительства массив, у меня есть условный оператор, который утверждает, что массив имеет такое же значение, предполагается случайное генерирование другого значения перечислимого типа

void constructSet(VoidPtr* animalArray, int size) 
{ 

    for(int i = 0; i < size; i++) 
    { 
     animalArray[i] = getAnAnimal(); 

     int k = 0; 

     while ((k < i) && (animalArray[i] == animalArray[k])) 
     {  
      animalArray[i] = getAnAnimal(); 

      k++; 
     }   
    } 

} 

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

+4

Один не может бросить целое число к объекту - вы бы также иметь утечку памяти здесь в качестве нового животного (а) теряются без удаления – UKMonkey

+1

Вы, вероятно, хотите использовать функцию завода, основанной на вашем 'перечисления '. Некоторое кастинг понадобится. И используйте 'Animal *' вместо 'VoidPtr'. –

+0

Я думаю, что вы пытаетесь сделать фабрику животных - там, где вы называете getAnimal (AnimalTypeEnum) ... Это называется заводской паттерн ... grr - избили пунш от @ πάνταῥεῖ – UKMonkey

ответ

3

Ваша ошибка в том, что при сравнении animalArray[i]==animalArray[k] вы сравниваете адреса перечислений, а не их значение. Правильное сравнение будет (отредактировано после комментария, очевидно, что это не то, что чистый код выглядит, но ошибка заключается в прохождении enum как void*)

*static_cast<Animal*>(animalArray[i])==*static_cast<Animal*>(animalArray[k]) 

Однако, вы должны пересмотреть хранение Animal как указатель. В C++ обычно нет причин выделять объекты по new (вам также не нужно работать с указателями на C++, если вам действительно не нужно). По крайней мере, не для простых проблем, как у вас.

+0

, когда я пытаюсь разыменовать мой указательный массив, он говорит: 'void не является типом указателя на объект' –

+1

Вы правы. Вам также сначала нужно будет использовать 'animalArray [i]' to Animal * '- **, но вся идея дизайна передачи значений enum' как указателей нарушена! ** – chtz

-1

Ваш алгоритм в constructSet не соответствует вашему описанию.

Я условный оператор, который гласит, если массив имеет такое же значение , то предположим, случайным образом генерировать другое значение ENUM

Две инструкции animalArray[i] = getAnimal(); и k++ должны быть в различных отраслях состояние. k++ следует перебирать, а animalArray[i] отличается от animalArray[k]. Предположим, например, что *animalArray[i] != *animalArray[0], но *animalArray[i] == *animalArray[1] вы вставляете его, даже если массив имеет одинаковое значение.

Кроме того, k следует повторно инициализировать каждый раз, когда вводится новое животное.

Вот альтернативный алгоритм. Я не проверял ошибки компиляции.

void constructSet(VoidPtr* animalArray, int size) 
{ 
    int attempt = 0; 
    for(int i = 0; i < size; i++) 
    { 
     animalArray[i] = getAnAnimal(); 
     int k = 0; 
     while ((k < i) && (*reinterpret_cast<const Animal*>(animalArray[i]) != *reinterpret_cast<const Animal*>(animalArray[k]))) 
      k++; 
     if (k < i && attempt < 12) { // retry? 
      --i; 
      ++attempt; 
     } 
     else // accept the animal 
      attempt = 0; 
    } 
} 
Смежные вопросы