Код ниже — моя структура и класс, содержащий ссылку на структуру.
typedef struct MESSAGE
{
int MessageType;
BSTR Name;
_bstr_t TimeStampIs;
} MESSAGE, *PMESSAGE;
typedef struct MESSAGENODE
{
PMESSAGE Message;
MESSAGENODE* pNext;
} MESSAGENODE, *PMESSAGENODE;class Message
{
private:
PMESSAGENODE MessageQueueFront;
PMESSAGENODE MessageQueueBack;
public:
bool AddMessageToQueue(PMESSAGE Message);
void DeleteMessageQueue(void){
PMESSAGE pMess;
while((pMess = GetMachineMessage()) != NULL)
{
if((pMess->DialysisDataIs))
SysFreeString(pMess->Name.Detach());
delete pMess;
}
}m;
int main()
{
PMESSAGE Message;
Message = new MESSAGE;
Message->Name=L"ABC";
Message->TimeStampIs=L"25252";
m.AddMessageToQueue(Message);
m.DeleteMessageQueue();
return 0;
}
Когда я компилирую приведенный выше код, я получаю следующие ошибки в
Функция DeleteMessageQueueошибка C2451: условное выражение типа ‘_bstr_t’ является недопустимой ошибкой
C2228: слева от .Detach должен быть класс / структура / объединение
Пара вещей, сначала мясо вашей ошибки
SysFreeString(pMess->Name.Detach());
Message::Name
является необработанным указателем BSTR, который, я уверяю вас, не имеет функции-члена, называемой Detach()
, _bstr_t
класс, однако, делает. Измените свою структуру на:
typedef struct MESSAGE
{
int MessageType;
_bstr_t Name;
_bstr_t TimeStampIs;
} MESSAGE, *PMESSAGE;
После этого вы можете удалить SysFreeString()
вызовите полностью, так как теперь и Name, и TimeStampIs являются интеллектуальными указателями и автоматически освобождаются при уничтожении объекта.
Как это
SysFreeString(pMess->Name);
Но нет веской причины использовать BSTR в таком коде. Нет также веских причин писать свой собственный класс связанного списка. Сделайте это простым способом (как указала Селби, это не единственная ошибка в вашем коде), я бы порекомендовал std::wstring
а также std::list
,
#include <string>
#include <list>
struct MESSAGE
{
int MessageType;
std::wstring Name;
std::wstring TimeStampIs;
};
class Message
{
private:
std::list<MESSAGE> queue;
public:
...
};
Большим преимуществом является то, что вам не нужно delete
что-нибудь. Так что все эти проблемы уходят.
Измените эту строку:
SysFreeString(pMess->Name.Detach());
К этому:
SysFreeString(pMess->Name);
pMess->Name = NULL;
Но это не единственная ваша проблема …
Кроме того, эта строка неверна:
Message->Name=L"ABC";
Вы назначаете WCHAR * на BSTR. Который для всех намерений и целей будет работать просто отлично, пока вы не отпустите его через SysFreeString. (Что может привести к сбою.)
Выделите вашу строку следующим образом:
pMess->Name = SysAllocString("ABC");
_Bstr_t — это полезный строковый класс, который внутренне содержит BSTR. Он заботится обо всех вызовах SysAllocString / SysFreeString для вас при преобразовании в / из собственных строк WCHAR *. Поэтому имеет смысл использовать его для Name так же, как вы используете его для TimeStampIs.