2010-09-21 11 views
12

W C++, mogę statycznie zainicjować tablicę, np .:Czy istnieje sposób na statyczną inicjalizację dynamicznie przydzielanej tablicy w C++?

int a[] = { 1, 2, 3 }; 

Czy istnieje prosty sposób zainicjować dynamicznie przydzielonego tablicy do zestawu natychmiastowych wartości?

int *p = new int[3]; 
p = { 1, 2, 3 }; // syntax error 

... Czy muszę koniecznie skopiować te wartości ręcznie?

+0

Co się sprzeciwia? Konieczność napisania kodu inicjującego wektor? Czas potrzebny na skopiowanie? Należy zauważyć, że wszelkie oszustwa kompilatora do zainicjowania dynamicznie przydzielonej tablicy wymagałyby tego samego kopiowania, ponieważ nie można zagwarantować, że przydzielona pamięć ma dokładnie taką samą zawartość. –

+0

Jeśli wydajność jest najważniejsza, dlaczego w ogóle dynamicznie alokujesz? Po co przekierowywać wskaźnik? Ponieważ i tak "statycznie inicjujecie" macierz, z pewnością wymiary macierzy są znane w czasie kompilacji? – fredoverflow

+0

Nie mam nic przeciwko, tylko pytam. Używam własnej klasy macierzy, która przechowuje dane w dynamicznie przydzielanej tablicy i pomyślałem, że to miłe, jeśli mogę zainicjować tę tablicę bez ręcznego kopiowania danych. :) – neuviemeporte

Odpowiedz

27

Ty można w C++ 0x:

int* p = new int[3] { 1, 2, 3 }; 
... 
delete[] p; 

Ale lubię wektory lepiej:

std::vector<int> v { 1, 2, 3 }; 

Jeśli nie masz C++ 0x kompilator, impuls może pomóc:

#include <boost/assign/list_of.hpp> 
using boost::assign::list_of; 

vector<int> v = list_of(1)(2)(3); 
+5

'+ 1' dla' std :: vector'. Jaki jest powód, aby nadal korzystać z własnych dynamicznych tablic? – sbi

+0

@sbi Zgoda, nie wydaje się, że jest dużo do wykorzystania podczas toczenia się, gdy wektory są o wiele przyjemniejsze. – EricBoersma

+0

@sbi - dostęp do rodzimych elementów tablicy jest szybszy niż ten sam z wektorem. Przetestowany. – Poni

1

Nie, nie można inicjować dynamicznie utworzonej tablicy w ten sam sposób.

W większości przypadków używasz alokacji dynamicznej w sytuacjach, w których statyczna inicjalizacja w zasadzie nie ma sensu. Na przykład, gdy masz tablice zawierające tysiące przedmiotów. To zwykle nie jest wielka sprawa.

8

Musisz przypisać każdy element tablicy dynamicznej jawnie (np for lub while)

Jednak składnia int *p = new int [3](); ma zainicjować wszystkie elementy do 0 (inicjalizacji wartości $ 8,5/5)

-1

Nigdy nie słyszałem o czymś takim to możliwe, że byłoby miło mieć.

Należy pamiętać, że przy inicjalizacji tablicy w kodzie tamtędy

int a[] = { 1, 2, 3 }; 

..... tylko zyskuje Ci łatwiejsze pisanie kodu, a nie wydajność. W końcu procesor wykona zadanie przypisania wartości do tablicy, tak czy inaczej.

+0

Ta linia nie generuje żadnego kodu ... jest to inicjalizacja kompilacji. – joeking

1

Korzystanie pomocnik zmienna:

const int p_data[] = {1, 2, 3}; 
int* p = (int*)memcpy(new int[3], p_data, sizeof(p_data)); 

lub jedna linia

int p_data[] = {1, 2, 3}, *p = (int*)memcpy(new int[3], p_data, sizeof(p_data)); 
+3

Zgodnie z ogólną zasadą (i dobrym nawykiem), nie powinieneś dynamicznie przydzielać obiektu w wywołaniu funkcji (tzn. Nie powinieneś nigdy wywoływać 'nowego' w argumencie funkcji). Powodem jest to, że kolejność oceny argumentów funkcji jest nieokreślona, ​​więc możesz skończyć dynamicznie alokując pamięć, wtedy ocena innego argumentu może rzucić wyjątek, wtedy ten dynamicznie przydzielony obiekt będzie przeciekał. [Herb Sutter ma więcej] (http://www.gotw.ca/gotw/056.htm). –

+0

+1 Chociaż jest to trochę tajemnicze i działa tylko dla POD. – fredoverflow

+1

James McNellis, ogólne zasady to tylko _general_ rules. I mają wyjaśnienia, aby zapewnić, że reguła pasuje do przypadku. W tym przypadku wszystko jest OK. – Abyx

4

Aby uniknąć niekończących push_backs, zazwyczaj zainicjować tr1::array i stworzyć std::vector (lub innego std Container) z wynik;

const std::tr1::array<T, 6> values = {T(1), T(2), T(3), T(4), T(5), T(6)}; 
std::vector <T> vec(values.begin(), values.end()); 

Jedyną uciążliwością jest to, że musisz podać liczbę wartości jawnie.

Można to oczywiście zrobić bez użycia numeru tr1::array;

const T values[] = {T(1), T(2), T(3), T(4), T(5), T(6)}; 
std::vector <T> vec(&values[0], &values[sizeof(values)/sizeof(values[0])]); 

Przez ciebie nie musisz podawać liczby elementów jawnie, wolę pierwszą wersję.

+0

+1 Czyste rozwiązanie! – fredoverflow

Powiązane problemy