2013-05-01 22 views
5

Szukałem, ale nie mogłem znaleźć odpowiedzi na to pytanie. Czy istnieje sposób, aby powiedzieć operatorowi new na nie wywoływać konstruktorów klas?Niezainicjowana tablica instancji klasy C++

MyObject* array = new MyObject[1000]; 

To zadzwoni MyObject() tysiąc razy! Chcę samodzielnie wypełnić przydzieloną pamięć i nie potrzebuję żadnych informacji zainicjowanych w konstruktorze. Używanie malloc() nie jest bardzo harmonicznym kodem C++ imho.

MyObject* array = (MyObject*) malloc(sizeof(MyObject) * 1000); 

Odpowiedz

4

Równoważnik C++ do malloc jest funkcją alokacji operator new. Można go używać tak:

MyObject* array = static_cast<MyObject*>(::operator new(sizeof(MyObject) * 1000)); 

Następnie można skonstruować konkretny obiekt o umieszczeniu nowego:

new (array + 0) MyObject(); 

Wymień 0 którykolwiek z offsetu chcesz zainicjować.

Zastanawiam się jednak, czy naprawdę chcesz sam dokonać tej dynamicznej alokacji. Być może lepiej będzie Ci odpowiadać std::map<int, MyObject> lub std::unordered_map<int, MyObject>, dzięki czemu możesz utworzyć numer MyObject w dowolnym indeksie.

std::unordered_map<int, MyObject> m; 
m[100]; // Default construct MyObject with key 100 
+0

Dzięki za odpowiedź. Jakiekolwiek wady używania rzutowania w stylu C nad 'static_cast'? Składnia budowy była dla mnie nowością. Szybkość jest kluczem, nie sądzę, że mapa pasuje, ponieważ naprawdę potrzebuję liniowej tablicy z ustaloną liczbą elementów. –

+0

@Niklas W tym przypadku nie ma żadnych wad. Rzut w stylu C jest zdefiniowany jako pierwszy z zestawu rzutów, które się powiodą. W tym przypadku będzie to odpowiednik 'static_cast'. Wolę jednak być jednoznaczny. Ponadto istnieje mnóstwo informacji o Stack Overflow na temat nowej składni miejsca docelowego. –

+0

@NiklasR Aby się upewnić: czy chcesz tworzyć obiekty sekwencyjnie (począwszy od indeksu 0 i wyższego), czy też dowolne pozycje w tablicy? Jeśli chcesz je sekwencyjnie, powolna odpowiedź 'std :: vector' jest odpowiednia. –

4

Rzeczywiście, używanie malloc nie jest bardzo harmoniczne z kodem C++. Ale malloc robi dokładnie to, o co prosisz. Obawiam się więc, że to, o co prosisz, nie jest zbyt harmoniczne z C++. Sądzę, że musisz zdecydować, jaki język chcesz programować w C lub C++.

Przypuszczam, że twoja jedyna prawdziwa opcja to przepisanie MyObject, aby nie miał żadnych konstruktorów, ale to nie jest tak naprawdę sposób C++.

3

prostu użyć std :: vector

std::vector<MyObject> v; 

v.reserve(1000); // allocate raw memory 
v.emplace_back(42); // construct in place 

o dostępie losowym (to jest (w zasadzie) co std :: vector robi wewnętrznie):

typedef std::aligned_storage<sizeof(MyObject), std::alignment_of<MyObject>::value>::type Storage; 
MyObject* myObjects(reinterpret_cast<MyObject*>(new Storage[1000])); 

new (myObjects + 42) MyObject(/* ? */); // placement new 
(*(myObjects + 42)).~MyObject(); 
0

Czy to czasowe? Czy to trwa "za długo"? Czy zdarza się to tylko raz podczas wykonywania twojego programu, jak na początku? Najpierw sprawdź, czy to rzeczywiście problem.

Czy naprawdę trzeba przydzielić 1000 obiektów w ten sposób?

Poza tym, jeśli konstruktorzy nie zostaną wezwani, w jaki sposób zostaną skonstruowane ... obiekty?

+0

To nie jest przydatna odpowiedź. Tak, stwierdziłem, że faktycznie * jest * problemem. Wszelkie koszty ogólne powinny zostać zmniejszone, jeśli to możliwe. –

+3

Bez problemu. To nie zostało poruszone przez innych komentatorów i nie wspomniałeś o tym w swoim pytaniu, więc pomyślałem, że to odpowiedni punkt widzenia. Teraz widzę, jak sftrabbit zapytał: "Zastanawiam się, czy naprawdę chcesz sam dokonać tej dynamicznej alokacji", która jest podobna do mojego drugiego komentarza. – codah