Является ли объединение в С++ фактически классом?
Младший разработчик спросил меня, можно ли перегрузить операторы присваивания для объединения с аргументами POD, чтобы соответствующий тип данных в объединении получался написанным, когда экземпляр объединения присваивается переменной этого типа. Я ответил, что я так не думал, но потом играл со следующим кодом. К моему удивлению, этот код действительно скомпилирован (с использованием g++ версии 4.6.3 на Ubuntu 12.04)
union unMember
{
float fData;
unsigned int uiData;
unMember():uiData(0) {};
unMember(float data):fData(data) {};
unMember(unsigned int data):uiData(data) {};
operator float() {return fData;};
operator unsigned int() {return uiData;};
unMember& operator=(float data) {fData = data;return *this;};
unMember& operator=(unsigned int data) {uiData = data; return *this;};
float GetFloat() const {return fData;};
};
int main () {
float fTest = 1.0;
unsigned int uiTest = 10;
unMember data = fTest;
unMember data2 = uiTest;
unMember data3 = data2;
float f = data.GetFloat();
return 0;
}
Это заставило меня понять, что я почти ничего не знаю о союзах (по крайней мере, в контексте С++, а не C), поскольку я действительно не ожидал, что смогу определить функции-члены для объединения таким образом. Вышеприведенный код подсказывает мне, что в С++ объединение реализуется внутри класса как класс, но на самом деле это случай в стандарте С++ или это просто некоторая причуда компилятора g++?
Кроме того, поскольку это действительно потрясло мое понимание того, что такое профсоюз, я бы приветствовал любые комментарии относительно того, целесообразно ли таким образом реализовать функции-члены для профсоюзов? Есть ли что-то по своей сути небезопасное в вышеупомянутой реализации моего союза?
В прошлом я использовал только союзы в классе контейнера, у которого есть индикаторная переменная, которая хранит, какой тип фактически был написан в союзе, и, честно говоря, я думал, что это их основное использование. Действительно ли это обычное явление для перегрузок конструкторов и т.д. Для профсоюзов таким образом?
Ответы
Ответ 1
Является ли объединение в С++ фактически классом?
Да. В С++ объединение - это класс: особый класс.
С++ 11: 9 Классы (p5):
Объединение - это класс, определенный с помощью объединения классов классов; он содержит только один элемент данных за раз
Действительно ли это типично для перегрузок конструкторов и т.д. для профсоюзов таким образом?
Объединение - это специальный класс с некоторыми ограничениями:
9.5 Союзы (p2):
Объединение может иметь функции-члены (, включая конструкторы и деструкторы), но не виртуальные (10.3) функции. Союз не должен иметь базовые классы. Объединение не должно использоваться в качестве базового класса.
11 Контроль доступа элемента (p3):
По умолчанию члены класса, определенные с ключевым словом class
, private
. Члены класса, определенные с ключевыми словами struct
или union
, по умолчанию public
.
Таким образом, вы можете перегружать конструкторы, деструкторы и операторы, аналогичные тем, которые вы можете выполнять в классе.