Обходной путь неограниченного объединения C ++ - PullRequest
0 голосов
/ 07 октября 2010
#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) - единственный вариант?

1 Ответ

3 голосов
/ 07 октября 2010

C ++ не допускает, чтобы элемент данных был любого типа, который имеет полноценный конструктор / деструктор и / или конструктор копирования, или нетривиальный оператор назначения копирования.

Это означает, что структура A может иметь только оператор назначения копирования по умолчанию (сгенерированный компилятором) или не иметь его вообще (объявлен как закрытый без определения).

Вы путаете назначение копированияоператор против оператора присваивания здесь.Оператор копирования копирования является особым случаем.В вашем примере A& operator =(const B & b) не классифицируется как оператор присваивания копии, это всего лишь оператор присваивания, и C ++ не ограничивает вас от использования его в классе, помещаемом в union.Но когда объект назначается путем копирования, оператор назначения копирования (который вы назвали оператором назначения по умолчанию ) будет по-прежнему вызываться.

Нет обходного пути, чтобы у вас был пользовательскийоператор копирования копирования.Первое решение, которое приходит на ум, состоит в том, чтобы этот оператор был свободной функцией, но это тоже недопустимо.

Поэтому вам нужно придумать какую-то альтернативную функцию вместо присваивания.Наиболее близким было бы использование какого-либо другого оператора, например <<:

#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 .

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...