AUTOSAR C++14 Rule A20-8-6

станд:: должен использоваться, чтобы создать объекты, принадлежавшие станд.:: shared_ptr.

Описание

Управляйте определением

станд:: должен использоваться, чтобы создать объекты, принадлежавшие станд.:: shared_ptr.

Объяснение

Вместо того, чтобы выделить память при помощи new оператор и преобразование получившегося необработанного указателя на std::shared_ptr объект, например:

class numberClass {
     numberClass(int n): number(n){}
   private: 
     int number;
}
int aNumber=1; 
std::shared_ptr<numberClass> numberPtr (new numberClass(aNumber)); 
Создайте std::shared_ptr возразите непосредственно использованию использования std::make_shared функция. Например:
auto numberPtr = std::make_shared<Number>(aNumber);

Используя std::make_shared предпочтен потому что:

  • Создание std::shared_ptr объект выполняется в одном динамическом выделении памяти и улучшает производительность во время выполнения. В противном случае, создавая необработанный указатель при помощи new оператор требует одного динамического выделения памяти и преобразования необработанного указателя на std::shared_ptr объект требует второго выделения. Второе выделение создает блок управления, который отслеживает подсчет ссылок совместно используемого ресурса и делает std::shared_ptr объект, знающий обо всех указателях на совместно используемый ресурс.

  • Создание std::shared_ptr объект с помощью std::make_shared безопасно от исключения. В противном случае исключение может находиться между динамическим выделением памяти с new оператор и последующее преобразование, ведя к утечке памяти. Исключение вызывает утечку памяти только в определенных контекстах, например, когда std::shared_ptr объект создается в аргументе функции мультипараметра, и другая оценка аргумента функции выдает исключение.

  • Можно использовать более краткий синтаксис. Вы не должны повторять тип данных объекта, который динамически выделяется.

Реализация Polyspace

Средство проверки отмечает создание std::shared_ptr объект от необработанного указателя, возвращенного new оператор.

Поиск и устранение проблем

Если вы ожидаете нарушение правила, но не видите его, обратитесь к Кодированию Стандартных Нарушений, Не Отображенных.

Примеры

развернуть все

#include <cstdint>
#include <string>

class Record {
    Record(std::string aName, std::string someInfo): name(aName), info(someInfo){       
    }
    private:
       std::string name;
       std::string info;
};

void addRecordToDataBase(std::shared_ptr<Record> aRecord, bool dataBaseIsFull);
bool checkDataBase(void); //Checks if database can accept more entries

void createRecord() {
    std::shared_ptr<Record> recordPtr1 (new Record("John", "Mechanic, New York")); //Noncompliant
    auto recordPtr2 = std::make_shared<Record>("Tom", "Plumber, Boston"); //Compliant
    
    addRecordToDataBase(std::shared_ptr<Record>(new Record("John", "Mechanic, New York")), checkDataBase()); //Noncompliant
    addRecordToDataBase(std::make_shared<Record>("Tom", "Plumber, Boston"), checkDataBase()); //Compliant
}

В этом примере правило нарушено каждый раз, когда new оператор возвращает необработанный указатель, и последующее преобразование создает std::shared_ptr объект от необработанного указателя.

В первом вызове addRecordToDatabase, следующая последовательность событий может произойти (до C++ 17):

  • Первая оценка аргумента. new оператор динамически выделяет память для Record объект.

  • Вторая оценка аргумента. Функциональный checkDataBase называется.

  • Продолжение первой оценки аргумента. Необработанный указатель получен из new преобразован в std::shared_ptr объект.

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

Проверяйте информацию

Группа: Общая сервисная библиотека
Категория: необходимый, автоматизированный
Введенный в R2020b