2016-08-08 12 views
1

Я проверяю один из моих проектов с Cppcheck 1,75, а для этого кода (пониженное для ясности):предупреждения Ложной производительности для auto_ptr типа принятого значением

class TJob 
{ 
public: 
    TJob(std::auto_ptr<ITask> task); 
    // ... 
private: 
    std::auto_ptr<ITask> m_task; 
}; 

TJob::TJob(
    std::auto_ptr<ITask> task // <-- HERE the performance warning 
    ): m_task(task) 
{ 
    trace("TJob ctr"); 
} 

Я получаю новую работу предупреждение:

Id: passedByValue

Резюме: параметр функции 'задачи' должны быть переданы по ссылке.

Сообщение: Параметр «задача» передается по значению. Он может быть передан как ссылка (const), которая обычно быстрее и рекомендуется на C++.

который, очевидно, является ложным положительным. На мой взгляд, это ошибка, потому что после этого предложения приводит к серьезной ошибке [1], но, возможно, есть переключатель, который я пропустил, или какой-либо шаблон, который я могу предоставить, чтобы объявить, что право собственности передано по auto_ptr ?

Я искал в Интернете для этого, и только я нашел до сих пор является то, что Cppcheck включает в себя некоторые проверки для Check for invalid usage of STL, например

- using auto pointer (auto_ptr) 

Я знаю, что auto_ptr не лучший выбор, но Wouldn Точно так же с unique_ptr? Может быть, здесь вмешиваются две проверки?

Помимо использования inline supression, можно ли подавлять предупреждения для этих случаев?


Edit: добавлена ​​сноска.
[1]Там нет серьезной ошибки, только недоразумение об использовании std::auto_ptr. Я как-то перепутал время компиляции с семантикой времени выполнения: владение не передается какой-то магией времени компиляции, а скорее во время выполнения, вызывая конструктор «copy».

+1

Что значит, что предложение приводит к серьезной ошибке? Владение еще будет передано 'm_task', не так ли? – songyuanyao

+0

Действительно? Тогда мне действительно нужно углубиться в это ... – Wolf

+3

Если 'task' передается по значению, то для' std :: auto_ptr my_task (sth); TJob tjob (my_task); ', право собственности передается из' my_task' в аргумент 'task', затем передается члену' m_task'; Если 'task' передается по ссылке, право собственности будет передано' m_task' напрямую. Не так ли? – songyuanyao

ответ

2

Он правильно обнаружил, что вы передаете по значению конструктору копии, когда можете пройти по ссылке и амортизировать одну из копий. Ваш оптимизатор почти наверняка исправит «проблему» для вас, но нет необходимости полагаться на нее.

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

+0

* 'потому что он сообщает вызывающему, что вы берете указатель' * - есть ли у вас ссылка, где это предлагается? Я помню, что я это где-то читал ... (Ну, как я уже сказал, «auto_ptr» - это плохо.) – Wolf

+0

auto_ptr функционально подобен unique_ptr, есть только один владелец. Однако это происходит из дней, предшествующих конструкторам перемещения, и поэтому конструктор копирования используется для передачи права собственности, оставляя скопированный с объекта в недопустимом состоянии, поэтому конструктор const const был «удален». –