2008-09-18 9 views
7

Предположим, у меня есть следующий код:Есть ли что-то неправильное с возвращаемыми значениями по умолчанию?

class some_class{}; 

some_class some_function() 
{ 
    return some_class(); 
} 

Это, кажется, работает очень хорошо и сохраняет меня от того, чтобы объявить переменную только, чтобы сделать возвращаемое значение. Но я не думаю, что когда-либо видел это в каком-либо учебнике или справочной информации. Является ли это спецификой для компилятора (visual C++)? Или это делает что-то неправильно?

ответ

16

Нет, это совершенно верно. Это также будет более эффективным, так как компилятор действительно может оптимизировать временное.

+0

На самом деле современные компиляторы часто могут опровергнуть именованную переменную, которая возвращается – 2008-09-18 20:32:13

1

Это совершенно законный C++, и любой компилятор должен его принять. Почему вы думаете, что это может сделать что-то неправильно?

+0

Просто я никогда не видел, чтобы она использовалась где-либо в моем ограниченном опыте с C++. – 2008-09-18 20:28:49

+0

Достаточно честный. Определенно используйте его, если нет причин использовать временную переменную, то вам этого не нужно! – 2008-09-18 20:29:38

5

Возврат объектов из вызова функции является «заводским» шаблоном проектирования и широко используется.

Однако вы должны быть осторожны, возвращаете ли вы объекты или указатели на объекты. Первый из них позволит вам скопировать конструкторы/операторы присваивания, что может быть больно.

2

Действительно, но производительность может быть не идеальной в зависимости от того, как она называется.

Например:

A a; 
a = fn(); 

и

A a = fn(); 

не то же самое.

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

Во втором случае используется конструктор копирования.

Умный достаточно компилятор будет решать, какие оптимизации возможны. Но если конструктор копирования предоставляется пользователю, я не вижу, как компилятор может оптимизировать временную переменную. Он должен вызывать конструктор копирования, и для этого он должен иметь другой экземпляр.

+1

Стандарт явно позволяет компилятору удалять конструктор копирования. – 2008-09-19 18:42:30

1

Это лучший способ сделать это, если ваш класс довольно легкий - я имею в виду, что сделать его копию не очень дорого.

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

Для более тяжелых классов, которые вы хотите удостовериться, не скопированы (скажем, например, изображение с большим растровым изображением), тогда неплохо передать такие вещи как ссылочный параметр, который затем заполняется, убедитесь, что не будут созданы какие-либо временные объекты.

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

2

Разница между примером Роба Уокера называется Оптимизация возвращаемого значения (RVO), если вы хотите использовать его для Google.

Кстати, если вы хотите, чтобы ваш объект возвращался наиболее эффективным образом, создайте объект в куче (т.е. через new) с помощью shared_ptr и верните shared_ptr. Указатель возвращается, а счетчик ссылок правильно.