2009-08-18 3 views
3

Как я могу получить массив указателей, указывающих на объекты (классы)?Массив указателей

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

+0

Указывает на определенный класс или классы, полученные от одного родителя или только любого класса? –

+0

нет нет, только любой класс – akif

+0

Массив переменной длины (VLA) - это нестандартное расширение компилятора. Они были добавлены в спецификацию C99 и никогда не будут добавлены в спецификацию C++. Они работают только из-за расширений компилятора, реализованных intel/gnu/microsoft. Просто используйте вектор, для чего он нужен. –

ответ

10

Вы можете сделать это с указателем на указатель на свой класс.

MyClass ** arrayOfMyClass = new MyClass*[arrayLengthAtRuntime]; 
for (int i=0;i<arrayLengthAtRuntime;++i) 
    arrayOfMyClass[i] = new MyClass(); // Create the MyClass here. 

// ... 
arrayOfMyClass[5]->DoSomething(); // Call a method on your 6th element 

В принципе, вы создаете указатель на массив ссылок в памяти. Первый новый выделяет этот массив. Цикл выделяет каждый экземпляр MyClass в этот массив.

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

+1

Исправьте меня, если я ошибаюсь (это было время), но не забудьте вызвать delete [], чтобы освободить, когда вы закончите. –

+0

Я не думаю, что он показал код, где вы удаляете - если срок службы массива длиннее одного вызова функции. Кроме того, изменение размера - это боль. Отсюда и предложение для классов коллекции векторов/списков. – Kieveli

+0

Должен ли я вызвать delete, если я использую векторы?Я буду динамически выделять память – akif

15

Вместо этого используйте std::vector. Он предназначен для динамического изменения размера коллекции по мере необходимости.

#include <vector> 
// ... 
std::vector<Class*> vec; 
vec.push_back(my_class_ptr); 
Class* ptr = vec[0]; 
+0

спасибо, я тоже рассмотрю – akif

+2

Вектор указателей по-прежнему имеет много возможностей для утечки, если вы используете алгоритмы STL на векторе. Попытайтесь использовать вектор объектов, а не указатели, когда сможете. – KJAWolf

+1

@KJAWolf: можете ли вы привести несколько примеров алгоритма STL, который вызывает утечку с помощью 'std :: vector '? –

3

Я не могу отредактировать или прокомментировать, поэтому я должен опубликовать его в ответ: Что сказал Рид Копси, но с одним исправлением. При обращении к элементам вашего массива указателей вы должны получить доступ к членам, как это:

MyClass ** arrayOfMyClass = new MyClass*[arrayLengthAtRuntime]; 
for (int i=0;i<arrayLengthAtRuntime;++i) 
    arrayOfMyClass[i] = new MyClass(); // Create the MyClass here. 

// ... 
arrayOfMyClass[5]->DoSomething(); // Call a method on your 6th element 

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

+1

Вы не изобрели здесь синдром для 'std :: vector'? : O Если это так, вам действительно стоит подумать о написании компилятора C++; и, возможно, создать собственный процессор. –

+0

Ну, это отчасти потому, что я научился писать свои собственные векторы, прежде чем я узнал о существовании std :: vector, и теперь это просто привычка;) –

4

Использование boost::ptr_vector и забывающие оба массива и указатель головные боли:

boost::ptr_vector<animal> vec; 
vec.push_back(new animal); 
vec[0].eat(); 

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

+0

Если Boost не является вариантом (к сожалению, похоже, что это так, где бы я ни был работают с кодом C++, по некоторым причинам), но TR1 - например вы используете последнюю версию g ++ или VC++ 2008 SP1, тогда 'std :: vector >' также будет делать трюк. –