使用手动内存管理参考?

时间:2012-07-03 05:35:13

标签: c++ pointers reference

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

现在我决定在一些代码中间我想调用它的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 &varname; 
                varnamep = new ClassName();
                varname = *varnamep; // I assume compiler will error here because I can't reassign a ref. 

我可以通过其他方式这样做吗?或者我应该把它弄糟并进行查找替换,以便将varname.转换为varname->?在这种特殊情况下,对于我的实际情况,我可能会实现一个成员函数reset()而不用担心这个实际问题。但我想知道是否有一些捷径可以有效地将引用作为指针处理(或者它可能会证明这是荒谬的废话)

2 个答案:

答案 0 :(得分:4)

鉴于ClassName varname,您可以执行此操作:

varname.~ClassName();
new (&varname) ClassName;

但我不推荐它。这使用了两个不太常见的C ++特性:显式析构函数调用和placement new。只有在你的分析器测量的性能有显着差异时才使用它,并且ClassName构造函数不能抛出异常。

如果ClassName::operator=符合您的要求(或者您可以根据需要修改它),您可以这样做:

varname = ClassName();

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

另一个常见的习语:

varname.swap(ClassName());

如果ClassName具有高效的swap方法,就像标准容器一样,这种方法很有效。这很微妙,如果您决定使用它,它可能值得评论。

答案 1 :(得分:2)

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

ClassName varname = .... ;

....

if (some condition) {
  varname = SomethingElse;
}

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