2009-04-12 8 views
8

¿Qué pasa si tengo esto:¿Es posible juntar varios objetos dentro de una unión?

union{ 
    vector<int> intVec ; 
    vector<float> floatVec ; 
    vector<double> doubleVec ; 
} ; 

Por supuesto, voy a utilizar sólo uno de los 3 vectores. Pero ... ¿qué sucede cuando se construyen los 3 vectores?
¿Los interceptores de los 3 vectores interferirían entre sí? (ya que los 3 de ellos están en la misma dirección de memoria)

Gracias.

Respuesta

14

El estándar actual de C++ no permite tipos que no sean POD dentro de uniones. Usted recibirá este error del compilador de gcc:

error: member ‘std::vector<int, std::allocator<int> > 
<anonymous union>::i’ with constructor not allowed in union 
error: member ‘std::vector<int, std::allocator<int> > 
<anonymous union>::i’ with destructor not allowed in union 

estándar Nueva C++ (C++0x) propone unrestricted unions, pero adds yet more object lifetime pitfalls to C++.

+0

Oh, entonces no es posible. Eso es lo que pensé y tiene perfecto sentido debido al problema que expliqué en la pregunta. Gracias. – GetFree

8

No puede haber uniones que contengan tipos de clases que no sean POD. Tu muestra no se compilará

Puede usar boost::variant como alternativa segura a las uniones en C. Vea el documentation on boost.org. Sin embargo, puede reconsiderar su diseño y usar polimorfismo. Depende de lo que estás tratando de lograr, por supuesto.

+0

Sí, sé Boost :: variant y Boost: cualquiera. Solo quería estar seguro de si esto sería posible o no antes de considerar un enfoque diferente. Gracias. – GetFree

+0

Puede tener uniones que contengan tipos de clase, pero deben ser POD. ver la respuesta de Checkers. –

+0

Iraimbilanja, tienes razón, por supuesto. Fijo. – avakar

2

Desde el estándar de C++, la sección 9.5:

Un objeto de una clase con un constructor no trivial (12.1), un constructor no trivial de copia (12.8), un no trivial destructor (12.4), o un operador copia no trivial asignación (13.5.3, 12.8) no pueden ser un miembro de un sindicato ,

Aquí, por "no trivial" leer "útil": -)

+0

Aún más que eso, trivial implica implícitamente definido. Si el constructor está definido en código, es intrínsecamente no trivial. –

1

Es posible que desee echar un vistazo a Boost.Variant que puede contener un único valor de varios tipos.

2

¿Los interceptores de los 3 vectores interferirían entre sí? (dado que los 3 están en la misma dirección de memoria)

El estándar C++ no permite su programa, por lo que (al menos) la implementación define lo que sucede.

Si, por ejemplo, su implementación invoca las tres construcciones predeterminadas, y todas aquéllas ubicadas, y almacena el puntero al espacio recientemente asignado, tiene una pérdida de memoria (las primeras dos asignaciones son sobreescritas por la tercera).

Si todos los destructores son invocados y todos ellos liberan "su" memoria, usted estará haciendo una doble libre (triple, acually); Es probable que esto corrompa la estructura de datos de asignación, lo cual es una cosa mala. Sé feliz si bloqueas, porque es mucho más difícil de depurar si no lo haces.

Creo que estos problemas pueden ser por qué el estándar no permite esto.

(Una cosa más sensorial podría ser solo construir por defecto la primera clase, pero eso aún no es sensorial, solo menos loco ...)

+0

Así que, básicamente, sería un desastre. Es lo que pensaba. Y como dices, es por eso que no está permitido en absoluto. – GetFree

Cuestiones relacionadas