Pregunta

Tengo una clase con plantilla ligera que contiene un par de objetos miembro que se utilizan muy raramente, y por eso me gustaría evitar llamar a sus constructores y destructores, excepto en los raros casos en que realmente se utilicen.

Para hacer eso, "declaro" en mi clase como esta:

template <class K, class V> class MyClass
{
public:
   MyClass() : wereConstructorsCalled(false) {/* empty */}
   ~MyClass() {if (wereConstructorsCalled) MyCallPlacementDestructorsFunc();}

   [...]

private:
   bool wereConstructorsCalled;
   mutable char keyBuf[sizeof(K)];
   mutable char valBuf[sizeof(V)];
};

... y luego utilizo la colocación de nuevo y borrar la colocación de configurar y derribar los objetos sólo cuando realmente se necesita para hacerlo.

Al leer el FAQ de C ++ que dice que cuando se utiliza la colocación nueva, tengo que tener cuidado de que la colocación está correctamente alineado, o habría tenido problemas.

Mi pregunta es, las matrices keyBuf y valBuf estar bien alineados en todos los casos, o hay algún paso adicional necesito tomar para asegurarse de que se alinearán correctamente? (Si es así, un paso no dependiente de la plataforma sería preferible)

¿Fue útil?

Solución

No hay ninguna garantía de que obtendrá la alineación apropiada. Las matrices se en general, sólo garantizados para ser alineado para el tipo de miembro. Una matriz de char está alineado para el almacenamiento de char.

La única excepción es que las matrices char y unsigned char asignados con new se dan alineación máxima, por lo que puede almacenar tipos arbitrarios en ellos. Sin embargo, esta garantía no se aplica en su caso lo que está evitando asignación del montón.

TR1 y C ++ 0x añadir algunos tipos muy útiles sin embargo:

std::alignment_of y std::aligned_storage juntos para darle una respuesta portátil (y el funcionamiento).

std::alignment_of<T>::value le da la alineación requerida para una T tipo. std::aligned_storage<A, S>::type le da un tipo POD con A alineación y S tamaño. Eso significa que se puede escribir de forma segura el objeto en una variable de tipo std::aligned_storage<A, S>::type.

(En TR1, el espacio de nombres es std::tr1, en lugar de sólo std)

Otros consejos

¿Puedo preguntar por qué quiere colocarlos en un char buffer? ¿Por qué no acaba de crear objetos puntero de K y V a continuación instanciarlo cuando lo necesite.

Tal vez yo no entiendo su pregunta, pero puedo no sólo que char *keyBuf[..size..]; ajuste inicialmente a NULL (no asignado) y asignarlo la primera vez que lo necesite?

Lo que estamos tratando de hacer con la colocación del nuevo negocio parece arriesgado y estilo de codificación mal.

De todos modos, la alineación de código depende de la implementación.

Si desea cambiar el código de uso alineación paquete pragma

#pragma pack(push,x)

// class code here

#pragma pack(pop) // to restore original pack value

Si x es 1, no habrá relleno entre sus elementos.

Aquí está un enlace para leer

http://www.cplusplus.com/forum/general/14659/

He encontrado esta respuesta Publicado por SiCrane en http: // www .gamedev.net / comunidad / foros / topic.asp topic_id = 455233 :?

  

Sin embargo, para las asignaciones estáticas, es menos derrochador de declarar el bloque de memoria en una unión con otros tipos. Entonces se garantizará el bloque de memoria para ser alineado con la alineación del tipo más restrictiva en la unión. Todavía es bastante feo de cualquier manera.

Suena como una unión puede hacer el truco!

Le recomiendo que nos fijamos en la plantilla boost::optional. Se hace lo que necesita, incluso si no se puede utilizar probablemente debería mirar a su puesta en práctica.

Utiliza alignment_of y type_with_alignment para sus cálculos de alineación y garantías.

Para hacer una muy larga historia muy muy corto esto no va a ayudar a su rendimiento de todos y hará que un montón de dolores de cabeza y no pasará mucho tiempo antes de dejarse atrapar por la escritura de su propia managemer memoria.

Colocación nuevo está muy bien para un POD (pero no te salvará nada), pero si usted tiene un constructor, en ese caso no va a funcionar en absoluto.

También no se puede depender del valor de su variable booleana si se utiliza la colocación nuevo.

La colocación nueva tiene usos pero no realmente para esto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top