Инициализируйте массив объектов в c ++ специальным значением - PullRequest
2 голосов
/ 21 ноября 2011

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

Я пытался использоватьНулевое определение в C ++, но обнаружил, что это просто значение «-1» int, и я не мог использовать его должным образом.Поэтому в основном мне нужно что-то отличить между свободной позицией в моем массиве и свободной.

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

Для любопытных я реализую простой хэш-набор и метод удаления вМой класс просто помечает позицию удаляемого элемента вместо некоторого восстановления.

Ответы [ 3 ]

1 голос
/ 21 ноября 2011

Прежде всего, нулевое определение не -1, а 0. Если у вас есть что-то вроде

class User
{
};

User RemovedClass;

вы можете иметь что-то вроде этого

User *arr[3];
arr[0] = new User();
arr[1] = 0;
arr[2] = &RemovedClass;

Здесь 0 - новый пользователь, 1 - эквивалент Java, равный нулю, 2 - маркер для удаленного класса.

EDIT

Как правило, когда вы видите Пользователь массив в Java , вам придется сопоставить его с Пользователь * массив в C ++.

После этих операций.

User a;
User b;
a = b;

в java a и b будет относиться к одному и тому же пользователю . В C ++ такой код уступает a и b, ссылаясь на два разных объекта User.

0 голосов
/ 21 ноября 2011

Я использую Boost :: опционально:

boost::optional<int> a;

if (!a) { std::cout << "no a!"; }

a = 5;

if (a) { std::cout << "a = " << *a; }

a = boost::none;

if (!a) { std::cout << "no a!"; }
0 голосов
/ 21 ноября 2011

Я думаю, что есть некоторая концепция, которую вам нужно понять.

В отличие от Java, когда вы создаете N-элементный массив User, он НЕ является массивом ссылок.Это действительно часть памяти, содержащая фактического пользователя N, который уже создан и инициализирован (т.е. конструктор уже запущен).(Ну, есть более сложные темы, такие как размещение новых, но я думаю, что это еще не совсем то, что вы ищете)

Так что это как-то противоречит, если вы сказали, что у вас есть "массив пользователей" и хотитеотслеживать, инициализирована ли определенная позиция.

Если только:

  1. Вы создаете не массив User, а массив "Pointer to User" (или другую ссылку типаauto_ptr).Таким образом, имеет смысл сказать, что определенный элемент является «нулевым»;или

  2. Ваша «инициализация» означает не создание экземпляра объекта, а явное действие инициализации (например, выполнение метода init () экземпляра User).Таким образом, имеет смысл сказать, что определенный элемент «не инициализирован».

(Прежде всего, когда вы пишете C ++, я рекомендую вам использовать std :: vector, а не массив. Однако я использую массив в этом ответе, чтобы придерживаться вашего вопроса)

Для случая 1 это строго вперед, просто используйте NULL (избегайте использования 0, потому что, хотя NULL определенкак 0 в большинстве систем, использование NULL на самом деле делает код более читабельным и более переносимым):

User* user[10] = {NULL};   // array of 10 pointer-to-User
user[0] = new User(...);
assert (user[0] != NULL);
assert (user[1] == NULL);

Для случая 2 у вас есть много других вариантов, например, сохранение другого логического массива для сохранения «инициализированного»пометить, или иметь обертку над пользователем для такого дополнительного флага, или просто добавить такой флаг в свой класс пользователя и т. д.

например,

User user[10];   // 10 element of User, which all of them is already created
//assume you have extra flag in User
user[0].init(...);  // explicity do some init work on user[0]
//......
if (! user[5].isInitialized()) {
  user[5].init(...);
}

(честно говоря, я думаю, что случай 2 не совсемчто вы ищете)

...