¿Puede una unión en C++ tener una función de miembro? ¿Cómo existe una unión con miembros de datos y funciones miembro si se crea un objeto?Unión en C++ son viables
Si supongo que sí, entonces son factibles en cualquier lugar. Si es así, ¿dónde?
¿Puede una unión en C++ tener una función de miembro? ¿Cómo existe una unión con miembros de datos y funciones miembro si se crea un objeto?Unión en C++ son viables
Si supongo que sí, entonces son factibles en cualquier lugar. Si es así, ¿dónde?
9,5/1
Una unión puede tener funciones miembro (incluyendo constructores y destructores), pero no virtuales (10.3) funciones. Una unión no debe tener clases base . No se usará una unión como una clase base. Un objeto de una clase con un constructor no trivial (12.1), una copia constructor no trivial (12.8), un destructor no trivial (12.4), o un no trivial operador de asignación de copia (13.5. 3, 12.8) no puede ser miembro de un sindicato , ni puede un conjunto de tales objetos
¿Qué quiere decir por Cómo hacer la unión con los miembros de datos y las funciones miembro existir si se crea un objeto? Las funciones miembro (no virtual) no ocupan espacio en una instancia de cualquier clase/unión.
No sé si es válido. Codepad acepta, los funcionamientos, y da la salida esperada de este programa
union x {
int t;
int k() { return 42;};
};
int main() {
x y;
y.t = y.k();
std::cout << y.t << std::endl;
}
simplemente he añadido algunas cosas más para @maraguida ejemplo. Lo escribí como respuesta solo para tener más espacio. Ilustra que no solo se pueden agregar funciones miembro, sino también funciones miembro estáticas y operadores.
#include <iostream>
union x
{
int t;
float f;
int k() { return t * 42;};
static int static_k() { return 42;};
float k_f() { return f * 42.0f;};
unsigned char operator [](unsigned int);
};
unsigned char x::operator [](unsigned int i)
{
if (i >= sizeof(x))
return 0;
return ((unsigned char *)&t)[ i ];
}
int main()
{
x y;
y.t = x::static_k();
std::cout << "y.t\t= " << y.t << std::endl;
std::cout << "y.f\t= " << y.f << std::endl;
std::cout << "y.k()\t= " << y.k() << std::endl;
std::cout << "x::static_k()\t= " << x::static_k() << std::endl;
std::cout << "y.k_f()\t= " << y.k_f() << std::endl;
std::cout << "y[ 0 ]\t= " << (unsigned int)y[ 0 ] << std::endl;
std::cout << "y[ 1 ]\t= " << (unsigned int)y[ 1 ] << std::endl;
std::cout << "y[ 2 ]\t= " << (unsigned int)y[ 2 ] << std::endl;
std::cout << "y[ 3 ]\t= " << (unsigned int)y[ 3 ] << std::endl;
}
Puede ser compilado con: g ++ -Wall union_func.cpp -o union_func
La salida es:
$ ./union_func
y.t = 42
y.f = 5.88545e-44
y.k() = 1764
x::static_k() = 42
y.k_f() = 2.47189e-42
y[ 0 ] = 42
y[ 1 ] = 0
y[ 2 ] = 0
y[ 3 ] = 0
Puede, por ejemplo, poner un operador de conversión a otro tipo de su necesidad, si tiene sentido para su necesidad.
También se puede hacer una unión de plantilla:
template <typename T>
union Foo {
public:
Foo() {}
Foo(const T& value) : _val(value) {}
const char* data() const {
return _tab;
}
std::size_t size() const {
return sizeof(T);
}
char operator[](unsigned int index) const {
return _tab[index];
}
private:
T _val;
char _tab[sizeof(T)];
}
El union
es una estructura de C, y no funciona bien con los tipos de C++ (hay una serie de advertencias en realidad). Sin embargo, ya existe un equivalente en C++, que funciona con todas las clases de C++ y clases definidas por el usuario, ¡y es incluso más seguro que la unión!
Behold Boost.Variant!
Se puede definir una boost::variant<std::string, Foo, char>
y va a asegurarse de que:
Y viene incluso con la excelente: boost::static_visitor<Result>
que le permite aplicar un método en la unión, independientemente de su tipo, y proporcionar verificación en tiempo de compilación para advertirle cuando haya olvidado una de las posibles tipos!
class MyVisitor: boost::static_visitor<int>
{
public:
int operator()(std::string const& s) const {
return boost::lexical_cast<int>(s);
}
int operator()(Foo const& f) const { return f.getAsInt(); }
int operator()(char c) const { return c; }
};
typedef boost::variant<std::string, Foo, char> MyVariant;
int main(int argc, char* argv[]) {
MyVariant v; // the std::string is constructed
if (argc % 2) { v = Foo(4); }
if (argc % 3) { v = argv[1][0]; }
if (argc % 5) { v = argv[1]; }
std::cout << boost::apply_visitor(MyVisitor(), v) << '\n';
return 0;
}
también ... es tan eficiente (rápido) como un union
, y no implica ninguna consulta dinámica como Boost.Any haría.
+1, nunca pensé que podría hacer eso con los sindicatos. Aprende algo nuevo todos los días ... –
+1 por algo que no sabía y escrito no solo porque "funciona para mí" – Flexo