我应该外包分配算法吗?(raii)
Should I outsource allocation algorithm? (RAII)
现在,我的课程具有构造函数,复制构造函数 and 复制分配分配操作员 when首先在(分配内存)上做同样的事情。破坏者正在处理内存。
class Register
{
public:
Register()
{
_trampoline_address = reinterpret_cast<BYTE*>(VirtualAlloc(nullptr, _trampoline_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
if (_trampoline_address == nullptr)
{
throw my_exception("Could not allocate memory for trampoline function.");
}
//....
}
~Register()
{
if (_trampoline_address != nullptr)
{
debug(VirtualFree(_trampoline_address, 0, MEM_RELEASE));
}
}
Register(const Register& other)
{
_trampoline_address = reinterpret_cast<BYTE*>(VirtualAlloc(nullptr, _trampoline_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
if (_trampoline_address == nullptr)
{
throw my_exception("Could not allocate memory for trampoline function.");
}
//...
}
Register& operator= (const Register& other)
{
_trampoline_address = reinterpret_cast<BYTE*>(VirtualAlloc(nullptr, _trampoline_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
if (_trampoline_address == nullptr)
{
throw my_exception("Could not allocate memory for trampoline function.");
}
//....
}
private:
BYTE* _trampoline_address;
static const int _trampoline_size = 20;
};
我考虑过将分配算法外包,因为我使用了3次,但是我不希望同一类类型的其他实例可以访问该功能。
那么,在RAII类中分配3个函数中的内存的正确解决方案是什么?
您可以创建一个private static
函数来帮助记忆分配:
static BYTE* allocate()
{
BTYE* ptr = reinterpret_cast<BYTE*>(VirtualAlloc(nullptr, _trampoline_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
if (ptr == nullptr)
{
throw my_exception("Could not allocate memory for trampoline function.");
}
return ptr;
}
然后,可以简化构造函数:
Register() : _trampoline_address(allocate()) { }
Register(const Register& other) : _trampoline_address(allocate()) { }
但是,复制分配运算符需要更多的工作。首先,从您发布的代码中尚不清楚,作业运算符的语义是什么。您是否应该将数据从RHS复制到LHS?如果没有,RHS在分配操作中扮演什么角色?您应该使用LHS拥有的内存?
Register& operator= (const Register& other)
{
// Prevent messing with memory when dealing with self-assignment.
if ( this != &other )
{
// Deal with the semantics of the operation.
}
return *this;
}
struct Register {
Register():
_trampoline_address(allocate())
{}
Register(Register const& o):
Register() // forward to default ctor
{
copy_data_from(o);
}
~Register() {
if (_trampoline_address)
debug(VirtualFree(_trampoline_address, 0, MEM_RELEASE));
}
Register& operator= (const Register& o) {
if (this != std::addressof(o))
copy_data_from(o);
return *this;
}
private:
void copy_data_from(Register const& o) {
Assert(_tranpoline_address);
// ...
}
static BYTE* allocate() {
return reinterpret_cast<BYTE*>(
VirtualAlloc(nullptr, _trampoline_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)
);
}
BYTE* _trampoline_address;
static const/*expr*/ int _trampoline_size = 20;
};
只有一个呼叫allocate
,但是我仍然将其放入static private
方法,因为它很混乱。
我还写了copy_data_from
,因为它将被两次使用(一次在Copy-CTOR中,一次分配一次)。
我个人很想让Register()
留下空的缓冲区,只有在使用时填充。如果缺少读取功能,则必须检查nullptr
和allocate()
:但是,无论如何他们都必须检查nullptr
。结果是一个更有效的移动和移动分配,创建空数组(稍后填充)的效率要高得多,等等。
在这种情况下, allocate()
事实更有用。您甚至可以拥有ensure_allocated()
,如果nullptr
。
_tranpoline_address
。您可以做两件事之一:
- 创建一个
private
函数,然后在每个构造函数中调用它。这仍然允许班级的其他成员功能在施工后调用该功能,但这应该是可以的(只是不称呼它!)。子类无法致电班级的私人成员,所以您应该没事的。 - 使用授权的构造函数。在一个构造函数中执行分配,然后从其他构造函数中调用该构造函数。显然,没有人可以明确称呼构造函数,因此应该关心您的担忧。可能的警告:您需要使用C 11符合编译器。
相关文章:
- 具有瞬态资源的RAII类
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 算法问题:查找从堆栈中弹出的所有序列
- 下面是排序算法O(n)吗
- KMP算法和LPS表构造的运行时间
- 为什么我的排序算法会更改数组值
- 求最大元素位置的分治算法
- 具有非整数边容量的最大流量的Dinic算法
- 使用RAII在给定次数的迭代后重新分配资源
- 到连接组件算法的问题(递归)
- STL算法函数在多个一维容器上的使用
- 读取最后一行代码算法 - c++ 时出现问题
- 括号更改 O(n) 算法
- 我应该外包分配算法吗?(raii)