Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > union и класы С++ |
Автор: __nazar__ 10.3.2008, 21:51 |
Здраствуйте. У меня возникла вот такая интересная ситуация при компиляции програмы: проблема в том что если о обединение входит клас то при компиляции возникает ошибка. Вот програма (написана на Visual C++): #pragma once #include <complex> #include "matrix.h" typedef class std::complex<long double> LongComplex; typedef enum EOperation {UNKNOWN,DEGREE,MUL,DIVD,AND,OR,XOR,NOT,DIV,MOD,PL US,MINUS} OPERATION; typedef enum ESwitcher {EMPTY,NUMBER,MATRICA,ACT} SWITCHER; typedef class CElement { public: SWITCHER GetElementType() {return sw;}; LongComplex& GetNumber(); OPERATION& GetOperation(); MATRIX& GetMatrix(); void SetNumber(LongComplex num); void SetOperation(OPERATION n); void SetMatrix(MATRIX& m); void Clear(); private: union { LongComplex number; OPERATION op; MATRIX matr; }element; SWITCHER sw; } ELEMENT,* PELEMENT; А вот ошибка error C2620: member 'CElement::number' of union 'CElement::<unnamed-tag>' has user-defined constructor or non-trivial default constructor. Но самое удивительное, то что MATRIX тоже класс но он ошибки не видайот потому что имеет конструктор и деструктор по умолчанию (то есть вобще их не имеет). Что можете посоветовать. как решыть ету проблему (обединение нужно использовать обязательно)? |
Автор: Daevaorn 10.3.2008, 22:02 | ||
Это и есть условие |
Автор: __nazar__ 10.3.2008, 22:05 |
так что мне делать, не переписывать же стандартну библиотеку ![]() Добавлено через 3 минуты и 39 секунд В принципе я зделал так: #pragma once #include <complex> #include "matrix.h" typedef class std::complex<long double> LongComplex; typedef enum EOperation {UNKNOWN,DEGREE,MUL,DIVD,AND,OR,XOR,NOT,DIV,MOD,PLUS,MINUS} OPERATION; typedef enum ESwitcher {EMPTY,NUMBER,MATRICA,ACT} SWITCHER; typedef class CElement { public: SWITCHER GetElementType() {return sw;}; LongComplex& GetNumber(); OPERATION& GetOperation(); MATRIX& GetMatrix(); void SetNumber(LongComplex num); void SetOperation(OPERATION n); void SetMatrix(MATRIX& m); void Clear(); private: /* union { LongComplex number; OPERATION op; MATRIX matr; }element;*/ char element[sizeof(LongComplex)]; SWITCHER sw; } ELEMENT,* PELEMENT; потом просто преобразовую типы, просто интересно может есть какие-то другие способи? |
Автор: korian 10.3.2008, 22:26 |
можно, например, использовать указатели в объединение, вместо самих объектов. |
Автор: __nazar__ 10.3.2008, 23:10 |
тогда и що 4 байта на каждий указатель |
Автор: bsa 11.3.2008, 00:25 |
__nazar__, в union будет выделено памяти только под элемент максимального размера. Т.е. если у тебя внутри union будет 3 указателя, то памяти будет выделено под объединения всего sizeof(void*). Объекты в union не должны иметь пользовательских конструкторов (и конструируемых полей), так как это может привести к порче данных одного объекта конструктором другого. |
Автор: Lazin 11.3.2008, 09:19 |
как вариант, вместо union-а можно использовать размещающее конструирование, забить буфер достаточной длины, и размещать там что угодно)), а вообще, конечно лучше boost::any, но any использует динамическую память... |
Автор: Earnest 11.3.2008, 11:30 |
Не используй union. Это наследие C и с классами плохо смешивается. Даже если держать там только указатели, нужно писать поддержку нормального создания \ освобождения, иначе получится небезопасно. А когда ты все это напишешь как следует, то получишь что-то вроде бустовских оболочек, только хуже. Так что согласна с Mayk: boost::variant. Mayk, у any и variant просто разные области применения. Там где нужен именно any, variant ужасно неудобно использовать - и наоборот. Но у аффтора явно случай variant - строго заданный набор типов. |