2010-10-10 17 views

Respuesta

60

En palabras simples, una función de miembro especial "trivial" significa literalmente una función miembro que hace su trabajo de una manera muy directa. La "manera directa" significa algo diferente para diferentes tipos de funciones especiales de miembros.

Para que un destructor y un constructor por defecto sean "triviales" significa literalmente "no hacer nada". Para el constructor de copias y el operador de asignación de copias, ser "trivial" significa literalmente "ser equivalente a la simple copia de memoria en bruto" (como copiar con memcpy).

Si usted mismo define un constructor, se considera que no es trivial, incluso si no hace nada, por lo que el compilador debe definir implícitamente un constructor trivial.

Para que una función miembro especial satisfaga los requisitos anteriores, la clase debe tener una estructura muy simplista, no debe requerir ninguna inicialización oculta cuando se crea o destruye un objeto, ni manipulaciones internas ocultas adicionales cuando está siendo copiado

Por ejemplo, si la clase tiene funciones virtuales, requerirá algunas inicializaciones ocultas adicionales cuando se crean objetos de esta clase (tabla de método virtual inicial y demás), por lo que el constructor de esta clase no calificará como trivial.

Para otro ejemplo, si una clase tiene clases base virtuales, entonces cada objeto de esta clase podría contener punteros ocultos que apuntan a otras partes del mismo objeto. Tal objeto autorreferencial no puede copiarse mediante una simple rutina de copia en bruto de la memoria (como memcpy). Manipulaciones adicionales serán necesarias para reinicializar adecuadamente los punteros ocultos en la copia. Por esta razón, el constructor de copias y el operador de asignación de copias para esta clase no calificarán como triviales.

Por razones obvias, este requisito es recursivo: todos los subobjetos de la clase (bases y miembros no estáticos) también deben tener constructores triviales.

+1

No hacer nada ... Entonces, ¿qué es un operador de asignación de copias? ;) –

+0

También se me permite tener un ctor no contributivo como (Rect r) {l = r ....} –

+2

@ acidzombie24: Hice algunas correcciones para cubrir las funciones de los miembros de copia. Tu segundo comentario no está claro para mí. Cualquier constructor definido por el usuario no es trivial, por lo que una vez que lo define, la clase ya no es un POD. – AnT

22

Un constructor de una clase A es trivial si todos de los siguientes son verdaderas:

  • Se define implícitamente (compilador sintetizó)
  • A no tiene funciones virtuales y no hay clases base virtuales
  • Todos las clases de base directa de un tener constructores triviales
  • las clases de todos los miembros de datos estáticos de A tener constructores triviales
+1

Lo siento si suena tonto, pero ¿se aplica a los destructores también? – Bateman

16

Hay respuestas correctas ya, pero aquí está la cita de la norma (que yo estaba buscando cuando me encontré con este post):

(§12.1/5) Un constructor por defecto es trivial si no es proporcionado por el usuario y si:
- su clase no tiene funciones virtuales (10.3) ni clases base virtuales (10.1), y
- no miembro de datos no estática de su clase tiene un aparato ortopédico o igual-inicializador, y
- todas las clases de base directa de su clase tienen constructores por defecto triviales, y
- para toda la los miembros de datos no estáticos de su clase que son del tipo de clase (o matriz de los mismos), cada clase tiene un constructor predeterminado trivial.

Esto es de C++ 11. C++ 03 carece del segundo elemento y utiliza la frase implícitamente declarada en lugar de no proporcionada por el usuario. Por lo demás, es idéntico.

Tenga en cuenta que esta especificación solo cubre constructores triviales predeterminados. La palabra atributo trivial también se puede usar en diferentes contextos, p. Copiar constructores.

Cuestiones relacionadas