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 に答える