2012-08-20 11 views
6

Ho una classe che ha (tra le altre cose) un puntatore al char senza segno che viene cancellato e riallocato per memorizzare alcuni dati da un altro array. Questo fatto con una funzioneCome posso fare l'equivalente di memcpy da un array raw a uno std :: vector?

class MyClass { 
    private: 
     unsigned char* m_Buffer; 
     int m_BufferSize; 
    public: 
     bool SetBuffer(int iSize, const unsigned char* pArray); 
}; 

bool MyClass::SetBuffer(int iSize, const unsigned char* pArray) { 
    bool bOK = false; 
    if (pArray != NULL && iSize > 0) { 
     delete [] m_Buffer; 
     m_Buffer = new unsigned char[iSize]; 
     memcpy(m_Buffer,pArray,iSize); 
     m_BufferSize = iSize; 
     bOK = true; 
     } 
     return bOK; 
    } 

Non mi piace questo codice a tutti, e mi piacerebbe davvero sostituire il puntatore con un std::vector<unsigned char>. La mia domanda è, come potrei eseguire l'aspetto memcpy? Se stavo passando un vettore come argomento alla mia funzione, potrei copiarlo usando gli iteratori, ma non ho il controllo sul tipo di argomento parametro, quindi sono bloccato con unsigned char*. C'è un modo di utilizzare gli iteratori o dimensionare il vettore alla giusta dimensione e quindi accedere alla sua matrice interna in modo che possa ancora copiare i dati con memcpy? O ancora meglio qualcosa usando gli iteratori ?? So che potrei usare un loop e push_back ma a me sembra dolorosamente inefficiente. Qualsiasi suggerimento sarà accolto con gratitudine.

risposta

19

In realtà, gli iteratori sono modellati da puntatori e pertanto i puntatori all'interno di un array sono considerati implementare il concetto RandomAccessIterator.

Pertanto:

m_buffer.assign(pArray, pArray + Size); 
+0

+1 Soluzione migliore –

+0

Questo ridimensionerà automaticamente il vettore o dovrei chiamare chiaro e impostare la dimensione di esso alla dimensione dell'array? – mathematician1975

+0

@ matematico1975 vedi [qui] (http://en.cppreference.com/w/cpp/container/vector/assign). Non devi chiamare chiaro, ridimensionare o altro. – juanchopanza

0

ho davvero vi consiglio di evitare di puntatori prime in questo modo. Penso che sia un'idea migliore per gestire std :: vector anziché i puntatori grezzi.

class MyClass { 
private: 
    std::vector<unsigned char> m_Buffer; 
    // No size member is needed, it is stored in m_Buffer 
public: 
    // No size parameter is needed, it is stored in Array 
    void SetBuffer(const std::vector<unsigned char> &Array); 
}; 

void MyClass::SetBuffer(const std::vector<unsigned char> &Array) { 
    std::copy(Array.begin(), Array.end(), m_Buffer.begin()); 
} 

Supponendo che le vostre forze Dessing di avere una cruda gestito per MyClass si prende cura di questo puntatore sui costruttori di copia e operator = (o sbarazzarsi di esso, invece):

MyClass::MyClass(const MyClass &Class) { 
    m_BufferSize = Class.m_BufferSize; 
    m_Buffer = new new unsigned char[m_BufferSize]; 
    memcpy(m_Buffer, Class.m_Buffer, m_BufferSize); 
} 

MyClass::operator =(const MyClass &Class) { 
    if (m_Buffer) delete [] m_Buffer; 
    m_BufferSize = Class.m_BufferSize; 
    m_Buffer = new new unsigned char[m_BufferSize]; 
    memcpy(m_Buffer, Class.m_Buffer, m_BufferSize); 
} 

Se don Si prenda cura dei puntatori gestiti MyClass nel costruttore di copie e operator = terminerà con due istanze di MyClass che gestiscono la stessa memoria.

+1

La domanda riguarda esplicitamente la sostituzione del puntatore corrente con la dimensione dell'array + con un 'vector'. –

+0

Sì, mi ero reso conto dopo la pubblicazione. Ma alla fine, il consiglio è lo stesso, penso che sia meglio usare 'std :: vector' invece i puntatori grezzi. –

Problemi correlati