如何解决防止类的临时实例化
如何防止实例化某个类的临时实例?
我尝试创建一个只能在lvalue实例上调用的方法,并在c'tor中调用该方法以防止在编译时对该类进行rvalue实例化,但这无济于事-该方法是甚至为该类的右值实例化成功调用。似乎c'tor忽略了当前正在构造右值实例的事实。只能使用左值方法调用。
我的目标是为 WinApi 返回的分配创建范围保护,该保护必须通过LocalFree
释放。
我想防止出现该类的临时实例,这会导致立即取消分配,从而违背了成为 scoped 后卫的目的。
这也可能导致不可预测的运行时行为,因为在函数调用后的一段时间内,LocalFree
释放的内存仍然可以访问。
解决方法
如果我正确地解释了问题,那么使用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}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。