Можно ли уничтожить объект раньше, чтобы его память использовалась последующими объектами?

0

C++: может ли объект быть уничтожен ранее, чтобы его память памяти была повторно использована последующими объектами?

В одном сегменте кода C++ в первой половине используются объекты a, b; во второй половине части создаются и используются объекты c, d.

Поскольку объекты a, b занимают много памяти, я хочу вручную уничтожить объекты a, b, когда заканчивается 1-я половина.

Я знаю, что могу использовать новые, удалить, чтобы добиться этого.

Но если я не использую новые и все еще хочу уничтожить объекты раньше (это означает, что до момента его завершения), могу ли я вручную вызвать его деструктор, чтобы его уничтожить? Таким образом, часть памяти может быть повторно использована для объектов 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, но они не включают отношения. Это частично перекрывает отношения. В этом случае это означает, что использование области невозможно? И последнее средство - использовать новые и удалить, не так ли?

  • 0
    Пожалуйста, добавьте пример кода, чтобы объяснить, почему вы должны уничтожить объект до истечения срока его действия . Вы всегда можете добавить дополнительный {} чтобы определить меньшие области.
  • 1
    Вы можете вручную вызвать деструктор исходного объекта, а затем использовать размещение new чтобы создать новый объект поверх этой памяти . Если вы делаете это, четко документируйте вещи, так как это может серьезно запутать / ввести в заблуждение читателей кода.
Показать ещё 11 комментариев
Теги:

4 ответа

3

Используйте новое место размещения и вызовите деструкторы вручную:

{
  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

  • 0
    Это звучит немного сложно. Я надеюсь использовать простой.
2

Вы можете разбить его на более мелкие функции:

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);
);

Если вы делаете что-то настолько сложное, что ни одно из них не подходит, вы можете объединиться с объединением или новым местом размещения; детали будут неудобно, в зависимости от ваших странных требований.

  • 0
    Вышеупомянутая половина и нижняя часть используют много общих переменных. Так что, похоже, метод scope {} делает его неудобным, поскольку я не хочу создавать функцию со слишком большим количеством параметров. Я предпочитаю использовать вручную управлять им. Является ли это возможным?
  • 0
    @ user1914692: Я не думаю, что это сделало бы это особенно неудобным. Вы должны были бы объявить общие переменные вне внутренних блоков; или, может быть, обернуть их в классе, и передать это в функции. Как я уже сказал, ручное управление с объединением или новым размещением может быть возможным; но с трудом, и будет зависеть от деталей ваших странных требований. Я бы постарался использовать обычные прицелы, прежде чем прибегать к такого рода странностям.
Показать ещё 1 комментарий
1

Как ваш фрагмент кода, вы можете написать как

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
  • 0
    Благодарю. Я придумаю другую ситуацию. В этой ситуации границы различных переменных переплетаются! Это так: область действия a перекрывается с областью действия b, но они не включают отношения. Это частичное совпадение отношений. В этом случае последнее средство - использовать новое и удалить, верно?
  • 0
    @ user1914692 конечно.
1

Вы можете управлять временем жизни вручную объектов в стеке, используя фигурные скобки.

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;
}

Но обратите внимание, что как только переменная выходит из области видимости, когда эта память используется снова, не указывается. Просто потому, что я объявил другой int имени, не означает, что он будет назначен адрес, где a z имел обыкновение быть.

  • 0
    Мне все равно, будет ли новая переменная точно использовать память старой переменной. Но я надеюсь, что компилятор достаточно умен, чтобы использовать память оставленных переменных. Это касается современных компиляторов?
  • 0
    Да, как только переменная выходит из области видимости, используя метод, который я показал, или решения Майка или Эренона, эта память становится свободной для использования для какого-либо другого объекта. Я просто хотел убедиться, что вы знаете, что это конкретное место не обязательно будет немедленно повторно использовано.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню