0
#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&) 还是 =(A&)) 而不仅仅是复制数据?还是不受限制的联合(即使在 Visual Studio 2010 中也不支持)是唯一的选择?

4

1 回答 1

3

C++ 不允许数据成员是具有完整构造函数/析构函数和/或复制构造函数或非平凡复制赋值运算符的任何类型。

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

您在这里混淆了复制赋值运算符与赋值运算符。复制赋值运算符是一种特殊情况。在您的示例中,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

以防万一,C++0x 中有不受限制的联合

希望能帮助到你。

于 2010-10-07T19:14:40.043 回答