2013-05-01 18 views
5

Ho cercato ma non ho trovato risposta a questo. C'è un modo per dire all'operatore new di di non chiamare i costruttori di classe?Array non inizializzato di classi C++

MyObject* array = new MyObject[1000]; 

Questo chiamerà MyObject() mille volte! Voglio riempire la memoria allocata e non ho bisogno di alcuna informazione inizializzata nel costruttore. L'utilizzo di malloc() non è molto armonico codice C++ imho.

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

risposta

4

Il C++ equivalente a malloc è la funzione di assegnazione operator new. Si può usare in questo modo:

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

quindi è possibile costruire un oggetto particolare nuova collocazione:

new (array + 0) MyObject(); 

Sostituire 0 con qualsiasi compensare si desidera inizializzare.

Tuttavia, mi chiedo se si vuole davvero fare da soli questa allocazione dinamica. Forse un std::map<int, MyObject> o std::unordered_map<int, MyObject> ti andrebbe meglio, in modo che tu possa creare un MyObject in qualsiasi indice.

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

Grazie per la risposta. Eventuali svantaggi dell'uso di un cast di stile C su 'static_cast'? La sintassi della costruzione era nuova per me. La velocità è la chiave, non credo che una mappa si adatti perché ho davvero bisogno di un array lineare di un numero fisso di elementi. –

+0

@Niklas In questo caso, non ci sono svantaggi. Il cast di stile C è definito come il primo di un set di cast che avrà successo. In questo caso, sarà equivalente a un 'static_cast'. Tuttavia, preferisco essere esplicito. Inoltre, ci sono molte informazioni su Stack Overflow sulla nuova sintassi del posizionamento. –

+0

@NiklasR Solo per essere sicuri: vuoi creare oggetti in sequenza (a partire dall'indice 0 e superiori) o in posizioni arbitrarie all'interno dell'array? Se li vuoi in sequenza, allora la risposta 'std :: vector' è lenta. –

4

Infatti, utilizzando malloc non è molto armonico con il codice C++. Ma malloc fa esattamente quello che stai chiedendo. Quindi temo che quello che chiedi non sia molto armonico anche con il C++. Immagino che tu abbia appena deciso quale linguaggio preferiresti programmare in C o C++.

Suppongo che l'unica altra vera opzione sia di riscrivere MyObject in modo che non abbia costruttori, ma che non sia proprio il modo C++.

3

basta usare std :: vector

std::vector<MyObject> v; 

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

per l'accesso casuale (questo è (praticamente) che cosa std :: vector fa internamente):

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

Avete cronometrato esso? Ci vuole troppo tempo? Questo si verifica solo una volta nell'esecuzione del tuo programma, come all'inizio? Determinare innanzitutto che si tratta di un problema.

Avete davvero bisogno di allocare i 1000 oggetti in questo modo?

A parte questo, se i costruttori non vengono chiamati, come saranno gli oggetti ... costruiti?

+0

Questa non è una risposta utile. Sì, ho determinato che in realtà * è * un problema. Eventuali spese generali dovrebbero essere ridotte, se possibile. –

+3

Nessun problema. Non è stato sollevato da altri commentatori e non l'hai menzionato nella tua domanda, quindi ho pensato che fosse un angolo pertinente. Ora vedo sftrabbit che mi ha chiesto "Mi chiedo se vuoi davvero fare da solo questa allocazione dinamica" che è simile al mio secondo commento. – codah

Problemi correlati