是否可以更早地销毁对象,使其存储内存被后续对象重用

Can the object be destroyed earlier, to make its storage memory be reused by subsequent objects?

本文关键字:对象 内存 存储 是否      更新时间:2023-10-16

C++:是否可以更早地销毁对象,使其存储内存被后续对象重用?

在C++代码的一个段中,在第半部分,使用对象 a、b;在后半部分,创建和使用对象 C、D。

由于对象 a、b 占用大量内存,我想在上半部分完成后手动销毁对象 a、b。

我知道我可以使用新的,删除来实现它。

但是,如果我不使用new,并且仍然想更早地销毁对象(这意味着,在其范围结束之前(,我可以手动调用其析构函数来销毁它吗?因此,这部分内存可以重用于对象 c 和 d.(我不需要释放内存,因为重用很好。

这是一个伪代码:

monsterClass a, b;
dragonClass c, d;
int i,j,k,l;
a = monsterClass(1000, 2000);
b = monsterClass(2000, 3000);
i = processMethod1(a, b);
j = ...;
k = ...;
l = ...;

// here, I want to destroy a, b, since they are not used any more, while occupy memory.
// The above half part and the below half part use many common variables. 
// So it seems scope {} method makes it inconvenient, 
// since I don't want to create a function with too many parameters.
// I don't want to use new or delete here. I hope it looks simple and not prone to error
// So can I use: ~a, ~b here?
c = dragonClass(400, 3000);
d = dragonClass(500, 4000);
processMethod2(c, d, i);
j = ...;
k = ...;
l = ...;

[更新1] 所以大多数人建议使用范围,这是一个好方法。我只是还是很好奇,我可以在那里使用 ~a 和 ~b 吗?我认为这似乎也是一种可行且方便的方法。

[更新2] 我遇到了另一种情况。在这种情况下,不同变量的范围是相互交织的!是这样的:a的范围与b的范围有重叠,但它们不包括关系。它是重叠部分关系。在这种情况下,这是否意味着无法使用范围?最后的手段是使用new和删除,对吧?

使用放置 new 并手动调用析构函数:

{
  char memory[std::max(sizeof(A),sizeof(B))];
  A* pA = new (memory) A();
  // use `pA`
  pA->~A(); // destruct A
  B* pB = new (memory) B();
  // use `pB`
  pB->~B(); // destruct B
} // `memory` goes out of scope

我建议阅读这个关于运算符 new 的优秀资源:http://en.cppreference.com/w/cpp/language/new

你可以把它分解成更小的函数:

void part1() {
    monsterClass a, b;
    a = monsterClass(1000, 2000);
    b = monsterClass(2000, 3000);
    processMethod1(a, b);
}

或较大函数中的块

{
    monsterClass a, b;
    // and so on
}
{
    dragonClass c, d;
    // and so on
}

或使用临时

processMethod1(
    monsterClass(1000, 2000);
    monsterClass(2000, 3000);
);

如果你正在做一些如此复杂的事情,以至于这些都不合适,你可能会搞砸一个工会,或者新的安置;细节会很繁琐,这取决于你奇怪的要求是什么。

您可以使用大括号手动控制堆栈上对象的生存期。

void foo()
{
    int x = 5;
    int y = 2;
    {          // This introduces a new scope
    int z = 3;
    }          // After this brace, z is now out of scope
    int a = x + y;
}

但请注意,一旦变量超出范围,何时再次使用此内存时,就不会指定。仅仅因为我声明了另一个名为 aint,并不意味着它将被分配z过去所在的地址。

作为你的代码片段,你可以写成

int i,j,k,l;
{
  monsterClass a(1000, 2000);
  monsterClass b(2000, 3000);
  i = processMethod1(a, b);
  j = ...;
  k = ...;
  l = ...;
}
// here, you want to destroy a, b, since they are not used any more, while occupy memory.
dragonClass c(400, 3000);
dragonClass d(500, 4000);
processMethod2(c, d, i);
j = ...;
k = ...;
l = ...;
// you could use the same technique if there are still e, f or so