Предположим, у меня есть следующий конструктор в классе C ++:
MyClass::MyClass()
{
char* buffer = malloc(100);
if (0 != someD3DXCallThatCanFail(..., buffer, ...))
{
free(buffer);
throw MyException(L"some message");
}
char* buffer2 = malloc(200);
if (0 != anotherD3DCallThatCanFail(..., buffer2, ...))
{
free(buffer);
free(buffer2);
throw MyException(L"another message");
}
.. more code here where buffer and buffer2 are still used
free(buffer);
free(buffer2);
}
РЕДАКТИРОВАТЬ: я ненавижу malloc / free и new / delete, но, к сожалению, мне нужно использовать буферы для загрузки текстур, которые затем передаются в ID3D10ShaderResourceView, ID3D10Buffer, буфер вершин и тому подобное. Все те требуют указателей на буфер.
Что я пытаюсь сделать, чтобы использовать исключения вместо возврата кодов ошибок.
Также я хочу создать буферы там, где они нужны, и освободить их сразу после того, как они больше не нужны.
Однако то, что выглядит уродливо, так это то, что в случае ошибок, независимо от того, возвращаю ли я коды ошибок или выкидываю исключения, я все равно должен помнить, чтобы очистить любой буфер, созданный до этого момента. Если у меня есть 10 буферов и 10 возможных точек ошибки, мне придется вызывать free () 100 раз (в каждом случае ошибки не забывайте освобождать каждый буфер).
Теперь предположим, что я или еще хуже, мой коллега хочет изменить логику и, скажем, добавить еще один буфер где-то посередине. Теперь ему нужно будет просмотреть все ошибки, которые могут возникнуть в остальной части метода, и добавить free () для этого буфера в каждом таком месте. Если он спешит, он может легко пропустить несколько таких мест, и у вас утечка памяти.
Это также раздувает код.
Ключевое слово finally решит эту проблему в Java или C #. Независимо от того, где в коде произошло исключение, я все равно очистил бы все эти буферы в "finally" (кстати, это не понадобится при сборке мусора). В C ++, насколько я понимаю, мне, возможно, придется создать переменную-член для любого такого буфера, а в деструкторе убедиться, что буферы очищены. Мне это тоже кажется уродливым, поскольку переменная-член с именем "pBuffer", даже приватная, является просто мусором, поскольку она используется только в одном методе (в нашем случае, конструкторе) и всегда будет NULL в остальной части время.
Должно быть, общая проблема, однако мне не удалось найти ответ с помощью поиска. Спасибо!