Сборка мусора в c ++ для неназначенных объектов

0

Я все еще изучаю все входы и выходы c++, и у меня есть конкретный вопрос о том, как он обрабатывает сборку мусора в отношении конкретной задачи, которую я делаю. У меня есть некоторый класс Vector2D, который содержит координаты для вектора, а также набор математических свойств, которые можно сделать для вектора (точечные продукты, вращение, масштабирование и т.д.). Выведенный ниже примерный заголовочный файл, дающий макет.

#ifndef VECTOR2D_H
#define VECTOR2D_H

class Vector2D{
private:
    double x, y;

public:    
    Vector2D(double var1, double var2, int coordinateType);
    Vector2D *  normalize();
    Vector2D *  rotate(double angle);
    Vector2D *  scale(double value);
};

Теперь я создал этот класс определенным образом, чтобы иметь определенную функциональность. Когда у меня есть объект Vector2D, скажем vec, я хотел бы иметь возможность работать с объектом и возвращать новый объект, а не изменять объект vec. Я также хотел, чтобы мы могли цеплять команды. Таким образом, я мог бы сделать что-то вроде scale vec а затем повернуть его с помощью команды vec = vec.scale(5).rotate(45). Каждый из этих методов просто возвращает новый объект Vector2D вместо изменения параметров vec по этой причине.

Мой вопрос приходит с сборкой мусора для этого. Я просто не знаю, как c++ справляется с этим и как я должен справиться с этим. технически в процессе выполнения vec.scale(5) создается новый объект Vector2D, который я затем выполняю .rotate(45), но затем никогда не использую его снова. Что еще, у меня нет никакого способа получить доступ к этому вновь созданному объекту, потому что я никогда никому не назначал его. Поэтому мои вопросы таковы.

1) Должен ли я беспокоиться об удалении этих новых объектов или c++ знает, чтобы удалить их самостоятельно?

2) Если мне нужно удалить его, как я могу это сделать без ссылки на этот объект?

3) Если (2) не может быть сделано, но это нужно сделать, является ли моя конструкция кода плохой практикой? Должен ли я изменить его, чтобы не делать то, что я сделал?

Благодарю!

  • 3
    Если возможно, вы должны вернуть Vector2D , а не Vector2D* . Тогда вам не нужно беспокоиться об этом. Вновь созданные векторы будут уничтожены автоматически.
  • 1
    Стандартный язык C ++ не требует, чтобы реализации имели или поддерживали сборки мусора; большинство не Вот почему динамическое выделение памяти не одобряется в системе с ограниченным объемом памяти. Вы можете перегрузить new оператор, чтобы выполнить сборку мусора.
Показать ещё 3 комментария
Теги:
garbage-collection

2 ответа

6
Лучший ответ

C++ не содержит сбор мусора. Всякий раз, когда вы создаете объекты с использованием operator new и operator new[], вы несете ответственность за удаление этих объектов с помощью delete или delete[], в зависимости от того, как был создан объект.

C++ позволяет использовать временные объекты, которые уничтожаются после их выхода из области видимости. Это позволяет реализовать API, который вы ищете: все, что вам нужно сделать, это объявить возвращаемые типы членов без указателя, пометить ваши функции const и вернуть объекты вместо указателей:

class Vector2D {
private:
    double x, y;

public:    
    Vector2D(double var1, double var2, int coordinateType);
    Vector2D  normalize() const;
    Vector2D  rotate(double angle) const;
    Vector2D  scale(double value) const;
};

Таким образом, вы можете связать вызовы так, как вы описываете:

vec = vec.scale(5).rotate(45);

Это создаст временный объект для возвращаемого значения scale(5), вызовет rotate(45) на нем, вернет результат обратно в vec и уничтожит два временных объекта, созданных в процессе.

  • 0
    Спасибо за это. У меня сложилось впечатление, что этот процесс был медленнее, чем возвращение указателей, потому что возвращение полного объекта требует передачи всей информации об этом объекте, тогда как указатель является ничем иным, как небольшой ссылкой. Моя программа требует интенсивных вычислений, поэтому меня также интересуют скорость и производительность.
  • 0
    @zephyr Это, безусловно, верно в теории. Однако компиляторам разрешено оптимизировать это очень агрессивно (см. «Оптимизация возвращаемого значения»), поэтому в этом случае оптимизатор может сделать это так, чтобы копирование не выполнялось.
Показать ещё 3 комментария
1

В системах с ограниченной памятью (например, встроенных системах) мы используем предварительно выделенные массивы объектов как пул памяти и выделяем из пула памяти.

Динамическое распределение памяти исключается из-за проблем с фрагментацией.

Коллекции мусора неодобрительно относятся к критическим критически важным событиям или срокам.

  • 0
    Это, конечно, идея, с которой я никогда не сталкивался раньше, но звучит как интересная. Но, честно говоря, простой возврат объекта звучит проще и требует меньше времени для исправления. Насколько я знаю сейчас, я не думаю, что пока что сталкиваюсь с ограничениями памяти, поэтому не думаю, что фрагментация станет для меня проблемой. Возможно, в будущем, но сейчас я думаю, что все в порядке. Тем более что этот объект Vector2D имеет минимальный объем памяти.

Ещё вопросы

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