通过SendMessage传递COleDateTime对象的替代方法及编译错误解决
解决MFC中SendMessage传递COleDateTime的编译错误及方案
错误原因分析
编译错误error C2102: '&' requires l-value的核心问题是:m_pEntry->GetMeetingDate()返回的是临时COleDateTime对象(右值),右值没有持久的内存地址,因此无法对其执行取地址操作。
可行解决办法
1. 修改GetMeetingDate返回值为左值引用
如果有权限修改GetMeetingDate的函数声明,将其改为返回COleDateTime的引用,这样返回的是对象本身(左值),就能直接取地址:
// 调整头文件中的函数声明 COleDateTime& GetMeetingDate(); // 实现文件中返回类成员变量的引用 COleDateTime& YourClass::GetMeetingDate() { return m_MeetingDate; // m_MeetingDate为类的持久化成员变量 } // 发送消息时直接取地址 return gsl::narrow<LRESULT>(&(m_pEntry->GetMeetingDate()));
注意:必须保证在SendMessage同步执行的整个过程中,该引用指向的对象不会被销毁,否则会出现野指针问题。
2. 将临时对象存入持久变量后传递地址
如果无法修改GetMeetingDate的返回类型,可以把临时对象存储到一个生命周期足够长的变量中(比如类成员变量),再传递该变量的地址:
// 在类中添加成员变量用于缓存 COleDateTime m_TempMeetingDate; // 发送消息前先缓存临时对象 m_TempMeetingDate = m_pEntry->GetMeetingDate(); // 传递缓存变量的地址 return gsl::narrow<LRESULT>(&m_TempMeetingDate);
关键:m_TempMeetingDate的生命周期必须覆盖SendMessage的整个处理流程,不能在消息处理完成前被销毁或覆盖。
3. 序列化传递(备选方案)
如果上述两种方式都不适用,可以利用COleDateTime的内置转换能力,将对象转为兼容long的数值类型传递,接收方再还原:
// 发送方:转换为时间戳数值 COleDateTime date = m_pEntry->GetMeetingDate(); DWORD dateValue = date.GetTime(); return gsl::narrow<LRESULT>(dateValue); // 接收方:还原为COleDateTime对象 COleDateTime receivedDate(static_cast<DATE>(wParam)); // 或根据参数位置取LPARAM
这种方式无需处理指针生命周期问题,本质是简化了最初的类型转换逻辑。
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

