如果我正确地解释了这个问题,你应该可以用RAII包装你的资源。
以下是对其外观的概述:
#include <Windows.h>
#include <string>
#include <stdexcept>
#include <utility>
template<typename T>
class [[nodiscard]] ScopedAlloc {
public:
ScopedAlloc(UINT uFlags, SIZE_T elems) :
hRes(LocalAlloc(uFlags, elems*sizeof(T)))
{
if (hRes == nullptr)
throw std::runtime_error("ScopedAlloc failed " +
std::to_string(GetLastError()));
}
// A constructor to take ownership of a HLOCAL created with LocalAlloc
explicit ScopedAlloc(HLOCAL res) : hRes(res) {
if(LocalSize(hRes) == 0)
throw std::runtime_error("ScopedAlloc failed " +
std::to_string(GetLastError()));
}
ScopedAlloc(const ScopedAlloc&) = delete; // or let it allocate and copy
ScopedAlloc(ScopedAlloc&& rhs) : hRes(std::exchange(rhs.hRes, nullptr)) {}
ScopedAlloc& operator=(const ScopedAlloc&) = delete; // or LocalReAlloc and copy
ScopedAlloc& operator=(ScopedAlloc&& rhs) {
std::swap(hRes, rhs.hRes);
return *this;
}
~ScopedAlloc() {
#ifndef NDEBUG
if (hRes) { // fill memory with garbage in debug mode
SIZE_T size = LocalSize(hRes);
if (size) std::memset(hRes, 0xdd, size); // 0xDD - Dead Memory pattern
}
#endif
LocalFree(hRes);
}
operator const T* () const { return static_cast<T*>(hRes); }
operator T* () { return static_cast<T*>(hRes); }
private:
HLOCAL hRes;
};
示例用法:
#include <iostream>
struct bar { int x, y; };
std::ostream& operator<<(std::ostream& os, const bar& b) {
return os << '{' << b.x << ',' << b.y << '}';
}
int main() {
ScopedAlloc<bar> foo(LMEM_FIXED | LMEM_ZEROINIT, 2);
foo[0] = {1, 2};
foo[1] = {3, 4};
std::cout << foo[0] << ", " << foo[1] << '\n'; // prints {1,2}, {3,4}
}