Подтвердить что ты не робот

Удаление ссылки

Это действительно? Допустимая практика?

typedef vector<int> intArray;

intArray& createArray()
{
    intArray *arr = new intArray(10000, 0);

    return(*arr);
}


int main(int argc, char *argv[])
{

    intArray& array = createArray();

    //..........

    delete &array;

    return 0;
}
4b9b3361

Ответ 1

Поведение кода будет вашим предполагаемым поведением. Теперь проблема заключается в том, что, хотя вы можете подумать, что программирование - это что-то писать для компилятора, это так же важно, как писать то, что другие программисты (или вы в будущем) поймут и смогут поддерживать. Код, который вы предоставили во многих случаях, будет эквивалентен использованию указателей для компилятора, но для других программистов он будет просто потенциальным источником ошибок.

Ссылки предназначены для псевдонима для объектов, которые управляются где-то еще, как-то иначе. В общем, люди будут удивлены, когда столкнутся с delete &ref, и в большинстве случаев программисты не ожидают, что будут выполнять delete по адресу ссылки, поэтому есть вероятность, что в будущем кто-то вызовет функцию забыть об удалении, и у вас будет утечка памяти.

В большинстве случаев лучше управлять памятью с помощью интеллектуальных указателей (если вы не можете использовать другие конструкторы высокого уровня, такие как std::vector s). Спрятав указатель за ссылкой, вы усложняете использование интеллектуальных указателей на возвращаемой ссылке, и, таким образом, вы не помогаете, но затрудняете работу пользователей с вашим интерфейсом.

Наконец, хорошая идея о ссылках заключается в том, что когда вы читаете их в коде, вы знаете, что время жизни объекта управляется где-то еще, и вам не нужно беспокоиться об этом. Используя ссылку вместо указателя, вы в основном возвращаетесь к единственному решению (ранее в указателях только C), и внезапно необходимо проявлять особую осторожность со всеми ссылками, чтобы выяснить, должно ли там управляться память или нет, чем больше усилий, больше времени, чтобы подумать об управлении памятью и меньше времени для беспокойства по решению актуальной проблемы - с лишним напряжением необычного кода люди растут, чтобы искать утечки памяти с помощью указателей и ожидать, что не будет никаких ссылок.

В нескольких словах: наличие памяти по ссылке скрывает от пользователя требование обработки памяти и затрудняет ее выполнение.

Ответ 2

Это действительно... но я не понимаю, почему вы когда-либо захотели это сделать. Это не исключение, и std::vector все равно будет управлять памятью для вас. Почему new это?

EDIT: если вы возвращаете новую память из функции, вы должны вернуть указатель, чтобы пользователи ваших головоломок не взорвались.

Ответ 3

Да, я думаю, это сработает. Но если я увижу что-то подобное в любом коде, над которым я работал, я бы разорвал его и реорганизовал сразу.

Если вы хотите вернуть выделенный объект, используйте указатель. Пожалуйста!

Ответ 4

Это действительно?

Да.

Допустимая практика?

Нет.

Этот код имеет несколько проблем:

  • Исправлено руководство по проектированию для наименее удивительного поведения: вы возвращаете то, что "выглядит" как объект, но должно быть удалено кодом клиента (это должно означать указатель - ссылка должна быть тем, что всегда указывает к действительному объекту).

  • ваше распределение может завершиться неудачей. Даже если вы проверите результат в функции выделения, что вы вернете? Недопустимая ссылка? Вы полагаетесь на распределение, выделяющее исключение для такого случая?

В качестве принципа проектирования рассмотрите либо создание объекта RAII, который отвечает за управление временем жизни вашего объекта (в данном случае умного указателя), либо для удаления указателя с тем же уровнем абстракции, который вы его создали:

typedef vector<int> intArray;

intArray& createArray()
{
    intArray *arr = new intArray(10000, 0);

    return(*arr);
}

void deleteArray(intArray& object)
{
    delete &object;
}

int main(int argc, char *argv[])
{
    intArray& array = createArray();
    //..........
    deleteArray(array);
    return 0;
}

Эта конструкция улучшает согласованность стиля кодирования (выделение и освобождение скрыты и реализованы с одинаковым уровнем абстракции), но все же имеет смысл работать с указателем, кроме ссылки (если только тот факт, что ваш объект динамически распределен, должен оставаться деталь реализации по какой-то причине).

Ответ 5

Это сработает, но я боюсь, что это неприемлемая практика. В мире С++ существует сильное соглашение о том, что управление памятью осуществляется с помощью указателей. Ваш код нарушает это соглашение, и он может покончить с тем, кто его использует.

Похоже, вы избегаете своего пути, чтобы не возвращать необработанный указатель этой функции. Если ваша проблема состоит в том, что вам нужно повторно проверить действительный указатель в главном, вы можете использовать ссылку для обработки вашего массива. Но createArray возвращает указатель, и убедитесь, что код, который удаляет массив, принимает его как указатель. Или, если это действительно так просто, просто объявите массив в стеке в главном и вообще откажитесь от функции. (Код инициализации в этом случае мог бы ссылаться на объект массива, который должен быть инициализирован, и вызывающий может передать свой стекный объект в код инициализации.)

Ответ 6

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

  • Ручное управление памятью
  • Нечеткая передача собственности на клиентскую сторону.

Но в этом вопросе есть тонкая точка, это требование эффективности. Иногда мы не можем вернуть значение pass-by, потому что размер объекта может быть слишком большим, громоздким, как в этом примере (1000 * sizeof (int)); По этой причине; мы должны использовать указатели, если нам нужно передать объекты в разные части нашего кода. Но это не означает, что реализация является приемлемой, потому что для такого рода требований есть очень полезный инструмент, это интеллектуальные указатели. Таким образом, дизайнерское решение зависит от программиста, но для такого рода конкретных деталей реализации программист должен использовать в этом примере приемлемые шаблоны, такие как интеллектуальные указатели.