C ++中的联合可以有成员函数吗?如果创建了一个对象,如何存在与数据成员和成员函数的联合?
如果我认为是,那么它们在任何地方都是可行的。如果是,那么在哪里?
答案 0 :(得分:33)
9.5 / 1
联盟可以拥有成员函数 (包括建设者和 析构函数),但不是虚拟的(10.3) 功能。工会不得有基础 类。工会不得用作 一个基类。一个类的对象 用一个非平凡的构造函数(12.1), 一个非平凡的拷贝构造函数(12.8), 一个非平凡的析构函数(12.4),或者一个 非平凡的复制赋值运算符 (13.5.3,12.8)不能成为a的成员 联盟,也不可能有这样的一系列 对象
你是什么意思如果创建了一个对象,如何与数据成员和成员函数联合?成员函数(非虚拟)在任何类/联合的实例中不占用空间。
答案 1 :(得分:10)
您还可以制作模板联合:
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)];
}
答案 2 :(得分:1)
union
是一个C结构,并不适用于C ++类型(实际上有很多注意事项)。但是,已经存在一个C ++等价物,它可以有效地处理所有C ++类和用户定义的类,甚至比联合更安全!
您可以定义boost::variant<std::string, Foo, char>
并确保:
它甚至带有优秀的:boost::static_visitor<Result>
,它允许你在联合上应用一个方法而不管它的类型,并提供编译时检查,以便在忘记其中一种可能的类型时发出警告!
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;
}
此外......它与union
一样高效(快速),并且不涉及任何像Boost.Any那样的动态查找。
答案 3 :(得分:0)
我不知道它是否有效。 Codepad接受,运行并提供此程序的预期输出
union x {
int t;
int k() { return 42;};
};
int main() {
x y;
y.t = y.k();
std::cout << y.t << std::endl;
}
答案 4 :(得分:0)
我刚刚在@maraguida示例中添加了一些内容。我写这篇文章只是为了获得更多空间。 它说明了不仅可以添加成员函数,还可以添加静态成员函数和运算符。
#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;
}
可以编译: g ++ -Wall union_func.cpp -o union_func
输出结果为:
$ ./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
例如,如果符合您的需要,您可以将转化运算符设置为您需要的其他类型。