Показаны сообщения с ярлыком GotW. Показать все сообщения
Показаны сообщения с ярлыком GotW. Показать все сообщения

С++: Безопасность относительно исключений при вызове функций

Этот пост - перевод статьи Герба Саттера: GotW #102: Exception-Safe Function Calls.

Простой вопрос

1. Что вы можете сказать о порядке выполнения функций f, g и h и выражений expr1 и expr2 в приведенных ниже фрагментах кода? Предпалагается, что expr1 и expr2 не содражат в себе вызовов других функций.
// Пример 1(a)
//
f( expr1, expr2 );
// Пример 1(b)
//
f( g( expr1 ), h( expr2 ) );

Вопросы посложнее

2. Разбирая доставшийся вам в наследство код, вы наткнулись на следующий фрагмент:
// Пример 2
 
// В заголовочном файле:
void f( T1*, T2* );
 
// В месте вызова:
f( new T1, new T2 );
Есть ли в этом коде проблемы с безопасностью относительно исключений или любые другие проблемы? Объясните.

3. Продолжая изучать старый код, вы обнаруживаете, что кому-то не нравился код, приведенный в примере 2, и позднее он был изменен на:
// Пример 3
 
// В заголовочном файле:
void f( std::unique_ptr<T1>, std::unique_ptr<T2> );
 
// В месте вызова:
f( std::unique_ptr<T1>{ new T1 }, std::unique_ptr<T2>{ new T2 } );
Какие улучшения привнес новый подход относительно старого (и привнес ли вообще)? Остались ли проблемы с безопасностью относительно исключений? Объясните.

4. Покажите, как можно реализовать функцию make_unique, которая бы решала проблемы с безопасностью в примере 3, и которую можно было бы вызывать следующим образом:
// Пример 4
 
// В заголовочном файле:
void f( std::unique_ptr<T1>, std::unique_ptr<T2> );
 
// В месте вызова:
f( make_unique<T1>(), make_unique<T2>() );

Использование умных указателей в C++

Этот пост - перевод статьи Герба Саттера: GotW #89 Solution: Smart Pointers.

Постановка проблемы

Простой вопрос

1. В каких случаях следует использовать shared_ptr а в каких - unique_ptr? Приведите как можно больше соображенией на эту тему.

Вопросы посложнее

2. Почему практически всегда следует использовать make_shared для создания объекта, которым будут впоследствии владеть shared_ptr? Объясните.

3. Почему практически всегда следует использовать make_unique для создания объекта, которым будет владеть unique_ptr? Объясните.

4. Что такое auto_ptr?

Использование умных указателей в C++ в качестве параметров

Этот пост является переводом статьи Герба Саттера: GotW #91 Solution: Smart Pointer Parameters.

Постановка проблемы

Простой вопрос

1. Каковы недостатки с точки зрения производительности следующего объявления функции? Объясните.
void f( shared_ptr<widget> );

Вопросы посложнее

2. Каковы недостатки с точки зрения корректности объявления функции из вопроса 1?

3. Ваш коллега реализует функцию f, которая принимает объект класса widget в качестве обязательного параметра, предназначенного только для чтения, и пытается выбрать из следующих возможных способов передать параметр (опустим ключевое слово const):
void f( widget* );             (a)
void f( widget& );             (b)
void f( unique_ptr<widget> );  (c)
void f( unique_ptr<widget>& ); (d)
void f( shared_ptr<widget> );  (e)
void f( shared_ptr<widget>& ); (f)
Для каких ситуаций какой способ подходит? Объясните свой ответ и укажите в каких случаях и куда конкретно стоит также добавить const к типу параметра. (Есть и другие способы передать параметр, но мы рассмотрим только представленные выше.)