Почему нам даже нужно, “удаляют []” оператор?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
32
задан David Nehme 19 October 2016 в 20:58
поделиться

6 ответов

Это - так, чтобы деструкторы отдельных элементов назвали. Да, для массивов ПЕРЕХОДНЫХ ПРИСТАВОК нет большой части различия, но в C++, у Вас могут быть массивы объектов с нетривиальными деструкторами.

Теперь, Ваш вопрос, почему бы не сделать new и delete ведут себя как new[] и delete[] и избавляются от new[] и delete[]? Я возвратился бы "Дизайн и Эволюция Stroustrup" книга, где он сказал, что, если Вы не используете функции C++, Вам не придется заплатить за них (во время выполнения, по крайней мере). Путем это стоит теперь, new или delete будет вести себя так же эффективно как malloc и free. Если бы delete имел delete[] значение, то были бы некоторые дополнительные издержки во время выполнения (как James Curran, на которого указывают).

38
ответ дан 27 November 2019 в 20:32
поделиться

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

единственная вещь, о которой я могу думать, состоит в том, что существует очень крошечный бит дополнительных издержек для обработки отдельного объекта как массива (ненужное" for(int i=0; i<1; ++i)")

6
ответ дан 27 November 2019 в 20:32
поделиться

Чертовски, я пропустил смысл вопроса, но я оставлю свой исходный ответ как заметку на полях. То, почему мы имеем, удаляют [], - то, потому что давным-давно мы имели, удаляют [cnt], даже сегодня, если Вы пишете, удаляют [9] или удаляют [cnt], компилятор просто игнорирует вещь между [], но компилирует хорошо. В то время C++ был сначала обработан фронтендом и затем питался к обычному компилятору C. Они не могли добиться цели хранения количества где-нибудь под занавесом, возможно, они даже не могли думать о нем в то время. И для обратной совместимости, компиляторы по всей вероятности использовали значение, данное между [] как количество массива, если нет такого значения затем, они получили количество от префикса, таким образом, это работало оба пути. Позже, мы ничего не ввели между [], и все работало. Сегодня, я не думаю, "удаляют []", необходимо, но реализации требуют это тот путь.

Мой исходный ответ (который упускает суть)::

"удаляют", удаляет отдельный объект. "удалите []", удаляет объектный массив. Для удаляют [] для работы, реализация сохраняет число элементов в массиве. Я просто перепроверил это путем отладки кода ASM. В реализации (VS2005) я протестировал, количество было сохранено как префикс к объектному массиву.

, Если Вы используете, "удаляют []" на отдельном объекте, переменная количества является мусором так катастрофические отказы кода. Если Вы используете, "удаляют" для объектного массива, из-за некоторого несоответствия, катастрофических отказов кода. Я протестировал эти случаи сейчас!

"удаляют, просто удаляет память, выделенную для массива". оператор в другом ответе не является правильным. Если объект будет классом, удалите, то назовет DTOR. Просто поместите интервал точки останова, DTOR кодируют и удаляют объект, точка останова совершит нападки.

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

9
ответ дан 27 November 2019 в 20:32
поделиться

Добавление этого начиная ни с какого другого ответа в настоящее время обращается к нему:

Массив delete[] не может использоваться на указателе на базовый класс никогда - в то время как компилятор хранит количество объектов, когда Вы вызываете new[], это не хранит типы или размеры объектов (как David, на которого указывают, в C++ Вы редко платите за функцию, которую Вы не используете). Однако скаляр delete может безопасно удалить через базовый класс, таким образом, он использовал и для очистки обычного объекта и для полиморфной очистки:

struct Base { virtual ~Base(); };
struct Derived : Base { };
int main(){
    Base* b = new Derived;
    delete b; // this is good

    Base* b = new Derived[2];
    delete[] b; // bad! undefined behavior
}

Однако в противоположном случае - невиртуальном деструкторе - скаляр delete должен быть максимально дешевым - он не должен проверять на количество объектов, ни на тип удаляемого объекта. Это делает, удаляют на встроенном типе или очень дешевом типе простых данных, поскольку компилятор должен только вызвать ::operator delete и ничто иное:

int main(){
    int * p = new int;
    delete p; // cheap operation, no dynamic dispatch, no conditional branching
}

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

5
ответ дан 27 November 2019 в 20:32
поделиться

У Marshall Cline есть приблизительно информация об этой теме .

3
ответ дан 27 November 2019 в 20:32
поделиться

delete [] гарантирует, что деструктор каждого участника называют (если применимо к типу), в то время как delete просто удаляет память, выделенную для массива.

Вот хорошее чтение: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=287

И не, размеры массива не хранятся нигде в C++. (Благодарен за то, что все указывают, что этот оператор неточен.)

2
ответ дан 27 November 2019 в 20:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: