2010-05-21 3 views
19

В C++, если мне нужен массив указателей, чтобы они могли указывать на разные объекты на последнем этапе, как выглядит синтаксис.C++ Array of Pointers

EDIT

мне нужно уточнить, что я пытаюсь сделать, я думаю. У меня есть класс foo, который имеет и добавляет метод. В методе добавления я беру ссылку на панель классов. Я хочу сохранить эту ссылку в массив указателей. Массив строки указателя необходимо будет постоянно расширять, с чем у меня нет проблем. Он создает и массирует кучу указателей, поэтому я могу позже назначить им барочные объекты. То, что я пробовал, кажется, терпит неудачу, поскольку класс bar не имеет конструктора по умолчанию, о котором компилятор жалуется. Это заставило меня думать, что я создаю и массиву реальных объектов, которые я не хотел делать.

Пожалуйста, нет stl и нет. Я не хочу слышать о том, как вы думаете, что это сумасшедший и т. Д., Что вы думаете.

+1

Это не дает строгого ответа на ваш вопрос, но в большинстве случаев было бы лучше использовать массив указателей. например std :: vector коллекция; –

+0

Что подразумевается под «без фактической инициализации объектов foo»? Кроме того, знаете ли вы, сколько элементов в массиве во время компиляции? – Naveen

+0

Какой код вы подготовили до сих пор? – Default

ответ

6

Например, если вам нужен массив из int указателей, это будет int* a[10]. Это означает, что переменная a представляет собой набор из 10 int* с.

EDIT

Я думаю, это то, что вы хотите сделать:

class Bar 
{ 
}; 

class Foo 
{ 
public: 

    //Takes number of bar elements in the pointer array 
    Foo(int size_in); 

    ~Foo(); 
    void add(Bar& bar); 
private: 

    //Pointer to bar array 
    Bar** m_pBarArr; 

    //Current fee bar index 
    int m_index; 
}; 

Foo::Foo(int size_in) : m_index(0) 
{ 
    //Allocate memory for the array of bar pointers 
    m_pBarArr = new Bar*[size_in]; 
} 

Foo::~Foo() 
{ 
    //Notice delete[] and not delete 
    delete[] m_pBarArr; 
    m_pBarArr = NULL; 
} 

void Foo::add(Bar &bar) 
{ 
    //Store the pointer into the array. 
    //This is dangerous, you are assuming that bar object 
    //is valid even when you try to use it 
    m_pBarArr[m_index++] = &bar; 
} 
+0

Не забудьте реализовать (или объявить как закрытый) оператор копирования, см. [Правило из трех] (http://stackoverflow.com/q/4172722). – basic6

46

Что вы хотите:

Foo *array[10]; // array of 10 Foo pointers 

Не следует путать с:

Foo (*array)[10]; // pointer to array of 10 Foos 

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

Я наконец получил синтаксис объявления указателя/массива в C, когда понял, что он описывает, как вы обращаетесь к базовому типу. Foo *array[5][10]; означает, что *array[0..4][0..9] (индекс в массиве из 5 элементов, затем индекс на массиве из 10 элементов, затем разыменование как указатель) будет обращаться к объекту Foo (обратите внимание, что [] имеет более высокий приоритет, чем *).

Это кажется обратным. Вы могли бы подумать, что int array[5][10]; (a.k.a. int (array[5])[10];) представляет собой массив из 10 int array[5]. Предположим, что так было. Затем вы получите доступ к последнему элементу массива, указав array[9][4]. Разве это тоже не выглядит наоборот? Поскольку объявление массива C является шаблоном, указывающим, как перейти к базовому типу (а не к составу выражений массива, как это можно было бы ожидать), объявления массивов и код с использованием массивов не должны прерываться.

+0

+1 Да, объявления C действительно имеют смысл, как только вы их понимаете :) – fredoverflow

+7

Для будущих посетителей этого вопроса: вы можете использовать [инструмент вроде этого] (http://cdecl.org/), который переводит эти объявления во что-то который напоминает английский, чтобы лучше понять, как объявляется переменная. – Sumurai8

3

Я хотел бы сделать это что-то вдоль этих линий:

class Foo{ 
... 
}; 

int main(){ 
    Foo* arrayOfFoo[100]; //[1] 

    arrayOfFoo[0] = new Foo; //[2] 
} 

[1] Это делает массив из 100 указателей на Foo-объекты. Но Foo-объекты фактически не созданы.

[2] Это один из возможных способов создания объекта и в то же время сохранить указатель на этот объект в первой позиции вашего массива.

3

Если вы не используете STL, то код выглядит много немного как C.

#include <cstdlib> 
#include <new> 

template< class T > 
void append_to_array(T *&arr, size_t &n, T const &obj) { 
    T *tmp = static_cast<T*>(std::realloc(arr, sizeof(T) * (n+1))); 
    if (tmp == NULL) throw std::bad_alloc(__FUNCTION__); 
     // assign things now that there is no exception 
    arr = tmp; 
    new(&arr[ n ]) T(obj); // placement new 
    ++ n; 
} 

T может быть любого типа POD , включая указатели.

Отметьте, что arr должно быть выделено malloc, а не new[].