今天在borland新闻组上看到这个问题,因为uion的所有成员都共享同样的内存,所以union中不能带有构造函数的对象。如下这个union:
union {
AnsiString str;
list<int> blah;
MyClass ok;
};
这三个对象都是带有构造函数的,如果这三个对象都调用各自的构造函数,它们将互相干扰对方的数据。
原贴作者定义了三个结构和一个联合来表示不同的消息:
typedef struct
{
TDateTime dtOccurance;//带有构造函数
int iEventId;
int iReasonId;
int iStatusId;
AnsiString sObject;//带有构造函数
} TSTR_BLOCKED_ITEM, *P_TSTR_BLOCKED_ITEM;
typedef struct
{
TDateTime dtOccurance;//带有构造函数
int iEventId;
int iReasonId;
int iStatusId;
AnsiString sUserSID;//带有构造函数
AnsiString sObject;//带有构造函数
} TSTR_BASIC_EVENT, *P_TSTR_BASIC_EVENT;
typedef struct
{
TDateTime dtOccurance;//带有构造函数
int iEventId;
int iReasonId;
int iStatusId;
AnsiString sUserSID;//带有构造函数
AnsiString sObject;//带有构造函数
AnsiString sSysTrayMsg;//带有构造函数
} TSTR_BROADCASE_EVENT, *P_TSTR_BROADCASE_EVENT;
typedef struct
{
union
{
TSTR_BLOCKED_ITEM d1;
TSTR_BASIC_EVENT d2;
TSTR_BROADCASE_EVENT d3;
};
} TSTR_EVENT_DATA; //用一个union表示三个不同的消息
编译器抱怨uion中不包含带有构造函数的对象。
后来Jason Cipriani回贴,给了两种解决方案:
(1):用一个结构体表示所有的消息
enum EventType {
etBlockedItem,
etBroadCaseEvent,
etBasicEvent
};
struct TSTR_EVENT_DATA {
EventType etType; // <-- event type
TDateTime dtOccurance;
int iEventId;
int iReasonId;
int iStatusId;
AnsiString sObject; // for all event types
AnsiString sUserID; // etBasicEvent and etBroadCaseEvent only, otherwise
"".
AnsiString sSysTrayMsg; // etBroadCaseEvent only, otherwise "".
};
void WriteEventToFile (const TSTR_EVENT_DATA *data) {
switch (data->etType) {
...
}
}
(2)用类继承来表示不同的消息
struct TSTR_EVENT_DATA {
TDateTime dtOccurance;
int iEventId;
int iReasonId;
int iStatusId;
virtual void WriteToFile (void) = 0; // <--- all events have this function
};
struct TSTR_BLOCKED_ITEM : public TSTR_EVENT_DATA {
AnsiString sObject;
void WriteToFile (void) { ... write this kind of event to file ... }
};
struct TSTR_BASIC_EVENT : public TSTR_EVENT_DATA {
AnsiString sObject;
AnsiString sUserID;
void WriteToFile (void) { ... write this kind of event to file ... }
};
struct TSTR_BROADCASE_EVENT : public TSTR_EVENT_DATA {
AnsiString sObject;
AnsiString sUserID;
AnsiString sSysTrayMsg;
void WriteToFile (void) { ... write this kind of event to file ... }
};
void WriteAllEventsToFile (const vector<TSTR_EVENT_DATA *> &events) {
for (size_t i = 0; i < events.size(); ++ i)
events[i]->WriteToFile();
}