| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > 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 - строго заданный набор типов. |