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

Синтаксис удаления С++

Я столкнулся с этим довольно необычным использованием "delete". Просто хотел узнать, удаляет ли следующая строка оба указателя или только первый?

delete ptr1, ptr2
4b9b3361

Ответ 1

Это, несомненно, ошибка. Здесь запятая - это оператор запятой, а не разделитель. Удаляется только первый указатель ptr1.

Второй указатель ptr2 - это просто выражение do-nothing.

Оператор delete имеет более высокий приоритет, чем оператор ,, поэтому выражение анализируется так, как если бы оно было написано:

(delete ptr1) , (ptr2)

и не так, как если бы он был написан:

delete (ptr1 , ptr2)

Если , имел более высокий приоритет, чем delete, тогда будет удален только второй указатель.

Ответ 2

Джеймс Макнеллис прав, что это оператор запятой, но он имеет неправильный приоритет оператора. Он (по-видимому) думает, что это работает как:
delete (ptr1, ptr2);

в этом случае он будет прав - он удалит только второй элемент. На самом деле, однако, delete также является оператором и имеет значительно более высокий приоритет, чем оператор запятой (который имеет как можно меньше приоритетов), поэтому он действительно работает как:

(delete ptr1), ptr2;

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

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

[Edit: Я вижу, что, когда я писал это, Джеймс исправил свой ответ. Мои извинения перед Джеймсом, но я думаю, что основной вывод стоит, поэтому я не удаляю это, по крайней мере пока.]

Ответ 3

Просто смотреть на него пугает меня.

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

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

Ответ 4

Рассмотрим этот пример кода:

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

Причиной, как уже ответил Джеймс, является приоритет оператора.

Ответ 5

Я бы не рекомендовал его, но будет работать следующее:

delete ( delete p1, p2 );

Это можно обобщить следующим образом:

delete ( delete ( delete p1, p2 ), p3 );
delete ( delete ( delete ( delete p1, p2 ), p3 ), p4 );