Я столкнулся с этим довольно необычным использованием "delete". Просто хотел узнать, удаляет ли следующая строка оба указателя или только первый?
delete ptr1, ptr2
Я столкнулся с этим довольно необычным использованием "delete". Просто хотел узнать, удаляет ли следующая строка оба указателя или только первый?
delete ptr1, ptr2
Это, несомненно, ошибка. Здесь запятая - это оператор запятой, а не разделитель. Удаляется только первый указатель ptr1
.
Второй указатель ptr2
- это просто выражение do-nothing.
Оператор delete
имеет более высокий приоритет, чем оператор ,
, поэтому выражение анализируется так, как если бы оно было написано:
(delete ptr1) , (ptr2)
и не так, как если бы он был написан:
delete (ptr1 , ptr2)
Если ,
имел более высокий приоритет, чем delete
, тогда будет удален только второй указатель.
delete (ptr1, ptr2);
в этом случае он будет прав - он удалит только второй элемент. На самом деле, однако, delete также является оператором и имеет значительно более высокий приоритет, чем оператор запятой (который имеет как можно меньше приоритетов), поэтому он действительно работает как:
(delete ptr1), ptr2;
Таким образом, он удаляет первый указатель, а результатом выражения является значение второго указателя, который не был удален, поэтому он все еще действителен (если он был ранее).
Я бы повторил вывод Мартина Йорка, и я думаю, что это поддерживает его. Я сомневаюсь, что даже один процент программистов на C++ знает С++, а также Джеймс Макнеллис - когда его ответ о том, что делает конструкция, ошибочен, это свидетельствует о том, что почти никто не узнает, что он на самом деле делает. Я бы сказал, что никто не может быть уверен, что он делает то, что было предназначено. Фактически, я предполагаю, что это было предназначено для удаления обоих объектов, которые он не должен делать (т.е. Не будет, если у компилятора нет ошибки).
[Edit: Я вижу, что, когда я писал это, Джеймс исправил свой ответ. Мои извинения перед Джеймсом, но я думаю, что основной вывод стоит, поэтому я не удаляю это, по крайней мере пока.]
Просто смотреть на него пугает меня.
Не используйте это, даже если оно законно, так как большинство людей вынуждено останавливаться и думать (и все равно ошибается (один из первых двух ответов должен быть неправильным, поскольку они противоречат друг другу, мой первый инстинкт - запятая проблемы оператора (но я не знаю))).
Даже сейчас я бы не ответил на этот вопрос, пока не написал пример и не протестировал его, и даже тогда я бы испугался угловых дел на языке, который мог бы вызвать проблемы.
Рассмотрим этот пример кода:
class foo
{
int _a;
public:
foo(int a) : _a(a) { }
~foo() { printf("~foo() %d\n", _a); }
};
int main(int argc, char** argv)
{
foo *p1 = new foo(1), *p2 = new foo(2);
delete p1, p2;
return 0;
}
Вывод:
~foo() 1
Причиной, как уже ответил Джеймс, является приоритет оператора.
Я бы не рекомендовал его, но будет работать следующее:
delete ( delete p1, p2 );
Это можно обобщить следующим образом:
delete ( delete ( delete p1, p2 ), p3 );
delete ( delete ( delete ( delete p1, p2 ), p3 ), p4 );