如何将 GetProfileBinary 的结果保存到智能指针中?
How do I save the result from GetProfileBinary into a smart pointer?
目前我在class中有以下成员变量:
BYTE *m_pbyImportColumnMappings;
在其中一个 classes 中,我们尝试从注册表中读取现有数据,如果不存在,我们将分配它。到目前为止,我是这样改的:
void CImportOCLMAssignmentHistoryDlg::ReadSettings()
{
UINT uSize;
m_dwImportFlags = theApp.GetNumberSetting(theApp.GetActiveScheduleSection(_T("Options")),
_T("ImportFlags"), ImportAssignment::None);
theApp.GetProfileBinary(theApp.GetActiveScheduleSection(_T("Options")),
_T("ImportColumnMappings"), (LPBYTE*)&m_pbyImportColumnMappings, &uSize);
// Reset memory buffer (if required)
if (uSize != (sizeof(BYTE) * 15))
{
if (uSize > 0)
{
delete[] m_pbyImportColumnMappings;
m_pbyImportColumnMappings = nullptr;
}
m_pbyImportColumnMappings = new BYTE[15];
// Default values
const gsl::span column_mappings(m_pbyImportColumnMappings, 15);
std::fill(begin(column_mappings), end(column_mappings), -1);
/*
m_pbyImportColumnMappings[0] = -1;
m_pbyImportColumnMappings[1] = -1;
m_pbyImportColumnMappings[2] = -1;
m_pbyImportColumnMappings[3] = -1;
m_pbyImportColumnMappings[4] = -1;
m_pbyImportColumnMappings[5] = -1;
m_pbyImportColumnMappings[6] = -1;
m_pbyImportColumnMappings[7] = -1;
m_pbyImportColumnMappings[8] = -1;
m_pbyImportColumnMappings[9] = -1;
m_pbyImportColumnMappings[10] = -1;
m_pbyImportColumnMappings[11] = -1;
m_pbyImportColumnMappings[12] = -1;
m_pbyImportColumnMappings[13] = -1;
m_pbyImportColumnMappings[14] = -1;
*/
}
}
我最初的更改是使用 gsl::span
来抑制关于使用指针运算的几个警告。但我不知道如何将 m_pbyImportColumnMappings
变成智能指针,因为我们试图从 GetProfileBinary
.
开始填充它
如果我能把它变成一个智能指针,那么当 class 超出范围时我就不需要释放内存了。
在相关回答中建议使用此代码:
theApp.GetProfileBinary(strSection, strEntry,
reinterpret_cast<LPBYTE*>(&pALI), &uBytesRead);
std::unique_ptr<BYTE[]> cleanup(reinterpret_cast<BYTE*>(pALI));
但是,鉴于我们正在处理 class 的成员变量而不是函数中的孤立变量,我不确定如何应用 cleanup
方法。
为了更简洁的代码,请考虑使用 std::vector
和临时缓冲区
std::vector<BYTE> m_mapping;
m_mapping.resize(15, -1);
...
UINT len = 0;
BYTE* temp = nullptr;
AfxGetApp()->GetProfileBinary(_T("setting"), _T("key"), &temp, &len);
std::unique_ptr<BYTE[]> cleanup(temp);
if (len == m_mapping.size() * sizeof(m_mapping[0]))
memcpy(m_mapping.data(), temp, len);
else
std::fill(m_mapping.begin(), m_mapping.end(), -1);
std::vector
还有自动清理和附加方法。
否则,使用std::unique_ptr
来替换此成员数据的new/delete
,可能有点像噩梦。示例:
m_mapping = nullptr;
GetProfileBinary("setting", "key", &m_mapping, &uSize);
if (uSize != (sizeof(BYTE) * 15))
{
{ std::unique_ptr<BYTE[]> cleanup(m_mapping); }
//delete memory immediately after exiting scope
//note the extra brackets
//allocate new memory and don't manage it anymore
m_mapping = std::make_unique<BYTE[]>(15).release();
if(m_mapping)
for (int i = 0; i < 15; i++) m_mapping[i] = -1;
}
这里我们无法利用std::unique_ptr
内存管理,它只是用来关闭警告。
这里不需要任何转换,因为 m_pbyImportColumnMappings
恰好是 BYTE
,而 GetProfileBinary
期望 BYTE
,它使用 [=21] 分配内存=]
目前我在class中有以下成员变量:
BYTE *m_pbyImportColumnMappings;
在其中一个 classes 中,我们尝试从注册表中读取现有数据,如果不存在,我们将分配它。到目前为止,我是这样改的:
void CImportOCLMAssignmentHistoryDlg::ReadSettings()
{
UINT uSize;
m_dwImportFlags = theApp.GetNumberSetting(theApp.GetActiveScheduleSection(_T("Options")),
_T("ImportFlags"), ImportAssignment::None);
theApp.GetProfileBinary(theApp.GetActiveScheduleSection(_T("Options")),
_T("ImportColumnMappings"), (LPBYTE*)&m_pbyImportColumnMappings, &uSize);
// Reset memory buffer (if required)
if (uSize != (sizeof(BYTE) * 15))
{
if (uSize > 0)
{
delete[] m_pbyImportColumnMappings;
m_pbyImportColumnMappings = nullptr;
}
m_pbyImportColumnMappings = new BYTE[15];
// Default values
const gsl::span column_mappings(m_pbyImportColumnMappings, 15);
std::fill(begin(column_mappings), end(column_mappings), -1);
/*
m_pbyImportColumnMappings[0] = -1;
m_pbyImportColumnMappings[1] = -1;
m_pbyImportColumnMappings[2] = -1;
m_pbyImportColumnMappings[3] = -1;
m_pbyImportColumnMappings[4] = -1;
m_pbyImportColumnMappings[5] = -1;
m_pbyImportColumnMappings[6] = -1;
m_pbyImportColumnMappings[7] = -1;
m_pbyImportColumnMappings[8] = -1;
m_pbyImportColumnMappings[9] = -1;
m_pbyImportColumnMappings[10] = -1;
m_pbyImportColumnMappings[11] = -1;
m_pbyImportColumnMappings[12] = -1;
m_pbyImportColumnMappings[13] = -1;
m_pbyImportColumnMappings[14] = -1;
*/
}
}
我最初的更改是使用 gsl::span
来抑制关于使用指针运算的几个警告。但我不知道如何将 m_pbyImportColumnMappings
变成智能指针,因为我们试图从 GetProfileBinary
.
如果我能把它变成一个智能指针,那么当 class 超出范围时我就不需要释放内存了。
在相关回答中建议使用此代码:
theApp.GetProfileBinary(strSection, strEntry,
reinterpret_cast<LPBYTE*>(&pALI), &uBytesRead);
std::unique_ptr<BYTE[]> cleanup(reinterpret_cast<BYTE*>(pALI));
但是,鉴于我们正在处理 class 的成员变量而不是函数中的孤立变量,我不确定如何应用 cleanup
方法。
为了更简洁的代码,请考虑使用 std::vector
和临时缓冲区
std::vector<BYTE> m_mapping;
m_mapping.resize(15, -1);
...
UINT len = 0;
BYTE* temp = nullptr;
AfxGetApp()->GetProfileBinary(_T("setting"), _T("key"), &temp, &len);
std::unique_ptr<BYTE[]> cleanup(temp);
if (len == m_mapping.size() * sizeof(m_mapping[0]))
memcpy(m_mapping.data(), temp, len);
else
std::fill(m_mapping.begin(), m_mapping.end(), -1);
std::vector
还有自动清理和附加方法。
否则,使用std::unique_ptr
来替换此成员数据的new/delete
,可能有点像噩梦。示例:
m_mapping = nullptr;
GetProfileBinary("setting", "key", &m_mapping, &uSize);
if (uSize != (sizeof(BYTE) * 15))
{
{ std::unique_ptr<BYTE[]> cleanup(m_mapping); }
//delete memory immediately after exiting scope
//note the extra brackets
//allocate new memory and don't manage it anymore
m_mapping = std::make_unique<BYTE[]>(15).release();
if(m_mapping)
for (int i = 0; i < 15; i++) m_mapping[i] = -1;
}
这里我们无法利用std::unique_ptr
内存管理,它只是用来关闭警告。
这里不需要任何转换,因为 m_pbyImportColumnMappings
恰好是 BYTE
,而 GetProfileBinary
期望 BYTE
,它使用 [=21] 分配内存=]