2012-08-20 11 views
6

Tengo una clase que tiene (entre muchas otras cosas) un puntero a char sin signo que se elimina y se reasigna para almacenar algunos datos de otra matriz. Una vez hecho esto con una función¿Cómo puedo hacer el equivalente de memcpy desde una matriz en bruto a 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; 
    } 

No me gusta este código en absoluto, y realmente me gustaría para reemplazar el puntero con un std::vector<unsigned char>. Mi pregunta es, ¿cómo voy a realizar el aspecto memcpy? Si estuviera pasando un vector como argumento a mi función, podría copiarlo usando iteradores, pero no tengo control sobre el tipo de argumento del parámetro, así que estoy atorado con unsigned char*. ¿Hay alguna forma de usar iteradores o dimensionar el vector al tamaño correcto y luego acceder a su matriz interna para poder copiar los datos con memcpy? ¿O incluso algo mejor usando iteradores? Sé que podría usar un ciclo y push_back, pero eso me parece dolorosamente ineficiente. Cualquier sugerencia será recibida con gratitud.

Respuesta

19

En realidad, los iteradores se modelan a partir de punteros y, por lo tanto, se considera que los punteros dentro de una matriz implementan el concepto RandomAccessIterator.

Por lo tanto:

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

+1 Mejor solución –

+0

¿Cambiará automáticamente el tamaño del vector o tendré que llamar a borrar y establecer el tamaño del mismo al tamaño de la matriz? – mathematician1975

+0

@ mathematician1975 ver [aquí] (http://en.cppreference.com/w/cpp/container/vector/assign). No tiene que llamar a borrar, cambiar el tamaño ni nada. – juanchopanza

0

Realmente te aconsejan evitar punteros primas de esta manera. Creo que es una mejor idea para administrar std :: vectores en lugar de los punteros sin procesar.

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()); 
} 

Suponiendo que sus fuerzas DESSING que tienen una prima gestionados para MyClass va a hacerse cargo de este puntero en constructores de copia y operator = (o deshacerse de él en su lugar):

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); 
} 

Si Don Cuide los punteros administrados MyClass en el constructor de copia y operator = terminará con dos instancias de MyClass administrando la misma memoria.

+1

La pregunta es explícitamente sobre reemplazar el puntero actual por un 'vector'. –

+0

Sí, me di cuenta después de la publicación. Pero al final, el asesoramiento es el mismo, creo que es mejor usar 'std :: vector' en lugar de punteros sin formato. –

Cuestiones relacionadas