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 >:@ 
} 

Y at-il solution de contournement pour pouvoir faire cette dernière ligne u1.a = u2.a avec exactement la même syntaxe, mais faites-le appeler le operator = (ne se soucient pas si c'est = (B &) ou = (A &)) au lieu de simplement copier des données? Ou est-ce que les syndicats non restreints (non pris en charge même dans Visual Studio 2010) sont la seule option?C++ solution sans restriction syndicale

+0

Pourquoi feriez-vous une union si une classe et son descendant? Qu'est-ce que vous avez besoin de cela? – JoshD

+0

Le point d'hériter de B est d'obtenir un "opérateur =" dans la structure que le compilateur peut gérer. J'ai mis le descendant dans l'union juste pour montrer que vous pouvez faire un "opérateur =" sur un membre d'union pour le type _any_ excepté le sien ... – Chris

+0

Le commentaire pour 'u1.a = u2.a;' devrait vraisemblablement être ' // Ceci appelle l'opérateur d'assignation par défaut' ... –

Répondre

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.

Cela signifie que la structure A ne peut avoir un opérateur d'affectation de copie par défaut (généré par le compilateur) ou pas du tout (déclarée privée sans définition).

Vous êtes déroutant copy assignment operator vs assignment operator ici. L'opérateur d'affectation de copie est un cas particulier. Dans votre exemple, A& operator =(const B & b) n'est pas classé comme un opérateur d'affectation de copie, il s'agit simplement d'un opérateur d'affectation et C++ ne vous empêche pas de le mettre dans la classe en cours d'union. Mais lorsque l'objet est assigné par copie, l'opérateur d'affectation de copie (que vous avez appelé un opérateur d'affectation par défaut ) sera toujours appelé.

Il n'existe aucune solution de contournement pour vous permettre d'avoir un opérateur d'affectation de copie personnalisé. La première solution qui vient à l'esprit est de faire en sorte que cet opérateur soit une fonction gratuite, mais cela n'est pas autorisé non plus.

Vous devez donc proposer une autre fonction au lieu de l'affectation. La chose la plus proche serait d'utiliser un autre opérateur, par exemple <<:

#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; 
} 

Cette volonté génèrerait les éléments suivants:

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

Juste au cas où, il y a unrestricted unions in C++0x.

Espérons que ça aide.

+0

Bummer. Le déclarer comme privé rend également le compilateur se plaindre. On dirait que je pourrais passer à gcc 4.6. – Chris

+0

gcc 4.6 prend en charge les unions non restreintes si vous activez le support C++ 0x en passant l'option '-std = C++ 0x' à la commande' g ++ '. Voici une liste des fonctionnalités C++ 0x dans gcc 4.6 - http://gcc.gnu.org/gcc-4.6/cxx0x_status.html –