Стандарты программирования на С++. 101 правило и рекомендация | страница 30
Обеспечьте, чтобы все ресурсы принадлежали объектам. Предпочтительно хранить все динамически выделенные ресурсы посредством интеллектуальных, а не обычных, указателей. Кроме того, следует выполнять каждое явное выделение ресурса (например, >new
) в отдельной инструкции, которая тут же передает ресурс управляющему объекту (например, >shared_ptr
). В противном случае может возникнуть утечка ресурсов, связанная с тем, что порядок вычисления параметров функции не определен (см. рекомендацию 31). Например:
>void Fun(shared_ptr
>// ...
>Fun(shared_ptr
> shared_ptr
Такой код небезопасен. Стандарт C++ предоставляет компилятору большую свободу действий по переупорядочению выражений, которые создают два аргумента функции. В частности, компилятор может чередовать выполнение этих двух выражений: сначала для обоих объектов может быть выполнено выделение памяти (при помощи оператора >new
), а уже затем будут вызваны два конструктора >Widget
. Такая последовательность действий может привести к утечке: если один из конструкторов сгенерирует исключение, то память для другого объекта никогда не будет освобождена (более детальную информацию по этому вопросу вы найдете в [Sutter02]).
Эта тонкая проблема имеет простое решение: следуйте приведенному выше совету и никогда не выделяйте в одной инструкции больше одного ресурса. Следует выполнять каждое явное выделение ресурса (например, >new
) в отдельной инструкции, которая тут же передает ресурс управляющему объекту (например, >shared_ptr
), например:
>shared_ptr
>Fun(sp1, sp2);
См. также описание дополнительных преимуществ такого стиля в рекомендации 31.
Можно чересчур увлечься интеллектуальными указателями. Обычные указатели вполне подходят для кода, в котором указываемый объект виден только в ограниченном объеме (например, внутри класса — типа указателя на узел дерева в классе >Tree
, использующийся для навигации по дереву).
[Alexandrescu00c] • [Cline99] §31.03-05 • [Dewhurst03] §24, §67 • [Meyers96] §9-10 • [Mitewski01] • [Stroustrup00] §14.3-4, §25.7, §E.3, §E.6 • [Sutter00] §16 • [Sutter02] §20-21 • [Vandevoorde03] §20.1.4
Стиль кодирования
Константа для одного является переменной для другого.
— Алан Перлис (Alan Perlis)
В этом разделе мы перейдем от вопросов проектирования к вопросам, которые появляются в основном при реальном кодировании.