sirve que programas programar para lenguaje ejemplos dev como comandos caracteristicas basicos c++ c++11 memory

que - lenguaje c++ ejemplos



¿Cuándo se permite que un tipo en c++ 11 sea memcpyed? (5)

De http://en.cppreference.com/w/cpp/types/is_trivially_copyable :

Los objetos de tipos trivialmente copiables son los únicos objetos de C ++ que pueden copiarse con seguridad con std::memcpy o ser serializados a / desde archivos binarios con std::ofstream::write()/std::ifstream::read() . En general, un tipo que se puede copiar de forma trivial es cualquier tipo para el cual los bytes subyacentes se pueden copiar en una matriz de caracteres char o unsigned y en un nuevo objeto del mismo tipo, y el objeto resultante tendría el mismo valor que el original.

Mi pregunta es la siguiente:

Si quiero copiar un tipo de clase, memcpy puede hacerlo muy rápido. Esto está permitido en algunas situaciones.

Tenemos algunos rasgos de tipo:

  • is_standard_layout.
  • is_trivially_copyable.

Lo que me gustaría saber es los requisitos exactos cuando un tipo será "copiable en modo bit".

Mi conclusión es que un tipo se puede copiar en modo bit a bit si los rasgos is_trivally_copyable y is_standard_layout son verdaderos:

  1. ¿Es exactamente lo que necesito para copiar bitwise?
  2. ¿Está demasiado restringido?
  3. ¿Está sin restricciones?

PD: por supuesto, el resultado de memcpy debe ser correcto. Sé que podría memcpy en cualquier situación pero incorrectamente.


Lo que entendi es

  • Un objeto debe tener constructor / destructor por defecto.
  • Operaciones predeterminadas de copiar y mover.
  • Sin funciones estáticas y virtuales tiene múltiples
  • Los especificadores de acceso para miembros de datos no estáticos previenen importantes
  • Las optimizaciones de diseño tienen un miembro no estático o una base que no es un diseño estándar.

puede probar si el tipo dado es pod (Datos antiguos) usando la función estándar is_pod :: value

Referencia: El lenguaje de programación C ++ 4ª edición.


Los objetos con constructores de copia trivial, operadores de asignación de copia trivial y destructores triviales se pueden copiar con memcpy o memmove

Los requisitos para que una función miembro especial de una clase T sea ​​trivial son

Copiar los constructores (cc) y copiar los operadores de asignación (ca)

  • No es proporcionado por el usuario (lo que significa que está definido de forma implícita o predeterminada), y si está predeterminado, su firma es la misma que la definida de manera implícita
  • T no tiene funciones miembro virtuales
  • T no tiene clases de base virtual
  • El cc / ca seleccionado para cada base directa de T es trivial
  • El cc / ca seleccionado para cada miembro de tipo de clase no estática (o matriz de tipo de clase) de T es trivial
  • T no tiene miembros de datos no estáticos de tipo calificado volátil (desde C ++ 14)

Destructores

  • No es proporcionado por el usuario (es decir, está definido de forma implícita o predeterminado)
  • No ser virtual (es decir, el destructor de la clase base no es virtual)
  • Todas las clases base directas tienen destructores triviales.
  • Todos los miembros de datos no estáticos de tipo de clase (o matriz de tipo de clase) tienen destructores triviales

El solo hecho de declarar la función como = default no lo hace trivial (solo será trivial si la clase también admite todos los demás criterios para que la función correspondiente sea trivial), pero escribir explícitamente la función en el código de usuario impide que sea trivial . Además, todos los tipos de datos compatibles con el lenguaje C (tipos POD) se pueden copiar de forma trivial .

Fuente: C ++ Concurrencia en acción y cppreference.com


Puede copiar un objeto de tipo T usando memcpy cuando is_trivally_copyable<T>::value es verdadero. No hay una necesidad particular de que el tipo sea un tipo de diseño estándar. La definición de ''copiable trivial'' es esencialmente que es seguro hacerlo.

Un ejemplo de una clase que se puede copiar con memcpy pero que no es un diseño estándar:

struct T { int i; private: int j; };

Debido a que esta clase utiliza un control de acceso diferente para diferentes miembros de datos no estáticos, no es un diseño estándar, pero aún es trivialmente copiable.


Si is_trivally_copyable<T>::value (o en C ++ 14 is_trivially_copyable<T>() ) no es cero, el tipo se puede copiar con memcpy .

Según el estándar de C ++, un tipo que se puede copiar de forma trivial significa:

los bytes subyacentes que componen el objeto se pueden copiar en una matriz de char o unsigned char. Si el contenido de la matriz de caracteres char o unsigned se copia nuevamente en el objeto, el objeto mantendrá su valor original.

Sin embargo, es importante darse cuenta de que los punteros también son tipos copiables trivialmente. Siempre que haya un puntero dentro de las estructuras de datos que va a copiar, tiene que asegurarse de que es correcto copiarlos a su alrededor.

Ejemplos en los que el peligro puede deberse simplemente al confiar en el objeto que se puede copiar de forma trivial:

  • Una implementación de estructura de árbol donde sus datos se colocan en una región contigua de la memoria, pero con nodos que almacenan direcciones absolutas en nodos secundarios
  • Creación de varias instancias de algunos datos con el fin de mejorar el rendimiento de subprocesos múltiples (con el fin de reducir los bloqueos de caché), con punteros de propiedad dentro, apuntando a cualquier lugar
  • Tiene un objeto plano sin punteros, pero con una estructura de terceros incrustada dentro. La estructura de terceros en algún momento en el futuro incluye un puntero que no debería existir dos o más veces.

Por lo tanto, siempre que se realice una copia, tenga en cuenta para comprobar si se podrían copiar los punteros en ese caso específico, y si eso estaría bien.

is_trivially_copyable cuenta que is_trivially_copyable es solo la "Comprobación de sintaxis" , no la "Prueba semántica" , en el lenguaje del compilador.