我有一个经常被引用的变量。它最初是一个自动变量。
现在我决定在一些代码中间我想调用它的 dtor 来重置它的状态,所以我打算解除分配并重新分配它。执行此操作的标准方法当然是对其调用 delete 并创建一个新的。
之前:
void func() {
ClassName varname;
while (varname.check()/*...*/) { if (varname.function()/*...*/) { /* bunches of code ... */
/*... some more code ... */
}
}
}
现在我想要:
void func() {
ClassName varname;
while (varname.check()/*...*/) { if (varname.function()/*...*/) { /* bunches of code ... */
if (key_code[SDLK_r]) { // Pressing R key should reset "varname"!
/* Here I want to dealloc and realloc varname! */
/* But if I declare varname as a ptr on line 2, */
/* line 3 (rest of code) must be refactored. */
}
}
}
}
我的第一次尝试是将第 2 行改成这样
ClassName *varnamep = new ClassName();
ClassName& varname = *varnamep;
但我不确定这是否意味着我稍后可以对其调用 delete 并重新分配引用!
delete &varname;
varnamep = new ClassName();
varname = *varnamep; // I assume compiler will error here because I can't reassign a ref.
我可以用其他方式做到这一点吗?或者我应该接受它并进行查找替换以将 varname.
转换为 varname->
?在这种特殊情况下,对于我的实际情况,我可能会实现一个成员函数 reset()
而不必担心这个实际问题。但我想知道是否有一些捷径可以有效地将引用视为指针(或者它可能会证明这是荒谬的废话)
最佳答案
给定 ClassName varname
,您可以这样做:
varname.~ClassName();
new (&varname) ClassName;
但我不推荐它。这使用了 C++ 的两个鲜为人知的特性:显式析构函数调用和 placement new。只有当它在性能上有显着差异时才使用它,正如您的探查器所测量的那样,并且 ClassName
构造函数不能抛出异常。
如果 ClassName::operator=
做了你需要的(或者你可以修改它来做你需要的),你可以这样做:
varname = ClassName();
这比使用显式析构函数调用后跟 placement-new 更容易理解。
另一个常见的习语:
varname.swap(ClassName());
如果 ClassName
有一个有效的 swap
方法,就像标准容器那样,这就有效。这是非常微妙的,如果您决定使用它,它可能值得评论。
关于c++ - 使用带有引用的手动内存管理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11305046/