C ++无限制联合解决方法

时间:2010-10-07 18:40:12

标签: c++ variable-assignment copy-constructor unions default-constructor

#include <stdio.h>

struct B { int x,y; };

struct A : public B {
    // This whines about "copy assignment operator not allowed in union"
    //A& operator =(const A& a) { printf("A=A should do the exact same thing as A=B\n"); }
    A& operator =(const B& b) { printf("A = B\n"); }
};

union U {
    A a;
    B b;
};

int main(int argc, const char* argv[]) {
    U u1, u2;
    u1.a = u2.b;    // You can do this and it calls the operator =
    u1.a = (B)u2.a; // This works too
    u1.a = u2.a;    // This calls the default assignment operator >:@
}

是否有任何解决方法可以使用完全相同的语法执行最后一行u1.a = u2.a,但让它调用operator =(不关心它是否=(B&amp;)或= (A&amp;))而不是仅复制数据?或者是不受限制的联合(即使在Visual Studio 2010中也不支持)唯一的选择吗?

1 个答案:

答案 0 :(得分:3)

C++ does not allow for a data member to be any type that has a full fledged constructor/destructor and/or copy constructor, or a non-trivial copy assignment operator.

这意味着结构A只能有一个默认的复制赋值运算符(由编译器生成)或根本没有它(声明为私有而没有定义)。

你在这里混淆了copy assignment operator vs assignment operator。复制赋值运算符是一种特殊情况。在您的示例中,A& operator =(const B & b)未被归类为复制赋值运算符,它只是一个赋值运算符,C ++不会限制您将其放入要合并的类中。但是,当通过复制分配对象时,仍将调用复制赋值运算符(您已调用默认赋值运算符)。

没有解决方法让您拥有自定义副本分配运算符。想到的第一个解决方案是让这个运算符成为一个自由函数,但这也是不允许的。

所以你必须提出一些替代功能而不是分配。最接近的是使用其他运算符,例如<<

#include <stdio.h>

struct B { int x, y; };

struct A : B
{
    A& operator =(const B& b) { printf("A = B\n"); return *this; }
};

union U {
    A a;
    B b;
};

A & operator << (A & lhs, const B & rhs)
{
    printf ("A & operator << (const A & lhs, const B & rhs)\n");
    return lhs = rhs;
}

int
main ()
{
    U u1, u2;
    u1.a << u2.b;
    u1.a << u2.a;
}

这将输出以下内容:

$ ./test 
A & operator << (const A & lhs, const B & rhs)
A = B
A & operator << (const A & lhs, const B & rhs)
A = B

以防万一,有unrestricted unions in C++0x

希望它有所帮助。