使用带有参考的手动内存管理

Using manual memory management with a reference?

本文关键字:内存 管理 参考      更新时间:2023-10-16

我有一个经常引用的变量。它最初是一个自动变量。

现在我决定在某些代码中间调用它的 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++功能:显式析构函数调用和放置 new。 仅当它对性能产生显著差异(由探查器测量)且ClassName构造函数无法引发异常时才使用此方法。

如果ClassName::operator=执行了您需要的操作(或者您可以对其进行修改以执行所需的操作),则可以执行以下操作:

varname = ClassName();

这比使用显式析构函数调用后跟 placement-new 更容易理解。

另一个常见的成语:

varname.swap(ClassName());

如果ClassName具有有效的swap方法,则此方法有效,例如标准容器。 这很微妙,如果您决定使用它,它可能值得评论。

标准方法是删除和创建新实例。只需重新分配变量:

ClassName varname = .... ;
....
if (some condition) {
  varname = SomethingElse;
}

并确保复制构造函数、赋值运算符和析构函数正确处理由 ClassName 管理的资源。