2016-02-10 13 views
4

Учитывая следующий кодВыполняет ли компилятор оптимизацию возвращаемого значения в случае возвращаемой переменной-члена?

class foo 
{ 
    private: 
     boost::shared_ptr <std::deque<foo> > m_ptr; 
    public: 
     foo(); 
     boost::shared_ptr <std::deque<foo> > get_my_ptr() 
     { 
      return m_ptr; 
     } 
}; 

И когда мы называем get_my_ptr() функцию как этот

boost::shared_ptr <std::deque<foo> > ptr = get_my_ptr() 

ли компилятор копия вызов конструктора для создания объекта PTR или он может выполнять nrvo? А в чем разница, мы будем называть его, как этот

const boost::shared_ptr <std::deque<foo> >& ptr = get_my_ptr() 
+0

Что такое 'boost :: shared'? Я только знаком с 'boost :: shared_ptr <>', и я несколько смущен тем, почему вы будете удерживать переменную-член «shared», а затем переходите к вызывающим абонентам ...?!? – DevSolar

+0

Извините, я исправил код. –

+0

ОК, забудьте мой (сейчас удаленный) комментарий. У меня нет идеи, что вы пытаетесь сделать там. Класс 'foo', содержащий общий указатель на' std :: deque < foo >' и передающий его по запросу? – DevSolar

ответ

3

С помощью NRVO компилятор допускает опускание копирования и перемещения, если выражение оператора return является именем локального, энергонезависимого объекта с автоматическим временем хранения, который не является параметром функции. Этот локальный объект создается непосредственно в хранилище, где в противном случае будет скопировано возвращаемое значение функции. Эти условия не выполняются для переменных-членов. Я это возможно только, если вы создали локальную копию элемента:

boost::shared_ptr<std::deque<foo>> get_my_ptr() 
{ 
    auto p = m_ptr; 
    return p; 
} 

В вашем примере копии т е р будет называться, что позволит увеличить счетчик ссылок разделяемого указателя. То же самое произойдет, если вы привяжете возвращаемый объект к ссылке const.

+0

Существует еще одно ограничение, которое не применяется в этом случае: локальный не может быть параметром функции. – juanchopanza

+0

@juanchopanza в этом случае? вы имеете в виду параметр 'this'? – hansmaad

+0

Нет, я имею в виду * этот пример *, в случае OP. Не C++ 'this'. – juanchopanza

2

компиляции не должен выполнять РВО, когда переменная член возвращается. Если это произойдет, объект останется с недопустимым членом.

+3

«Если это так», это граничная метафизика. Вы могли бы также представить, что объект в конечном итоге поделится своим членом с вызывающим. – juanchopanza

+0

@juanchopanza, это будет интересный trek для переменной-члена - совместно используемый вызывающим и объектом. –