Действительно ли более эффективно возвратить ссылку константы

Может быть, я не совсем понимаю ваш вопрос, но когда я открываю файл Word и создаю таблицу с 1 строкой (в качестве заголовка) и 2 столбцами и вводю «Страна» и «Партнер», тогда я могу создать новую строку в эта таблица с этим кодом:

Option Explicit

Sub addRow()
Dim tbl As Table

'set tble variable to Table with Index 1 in your document
Set tbl = ActiveDocument.Tables(1)

'add a row to this table at the end
tbl.Rows.Add

'get last row in this table
Dim lastRow As Variant
lastRow = ActiveDocument.Tables(1).Rows.Count

'write to the last row
ActiveDocument.Tables(1).Cell(lastRow, 1).Range = "your value in last row / column 1"
ActiveDocument.Tables(1).Cell(lastRow, 2).Range = "your value in last row / column 2"


End Sub

Вы сказали, что в вашем списке только одна строка. Этот код теперь добавляет строку и заполняет в столбцах 1 и 2 значение, которое находится справа от знака равенства. До сих пор неясно, что такое UT и откуда он взялся. Но в любом случае вы можете получить доступ к последним ячейкам с помощью этого кода.

12
задан Blair Conrad 9 November 2008 в 12:09
поделиться

3 ответа

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

По-другому, функция может возвратить константу или не ссылку константы на объект, объем которого не ограничен функциональным контекстом. Типичным примером является пользовательское operator<<:

std::ostream & operator<<(std::ostream &out, const object &obj)
{
   out << obj.data();
   return out;
}

К сожалению, возврат значением имеет свой недостаток производительности. Как Chris упомянул, возвращение объекта значением включает копию временного объекта и его последующего разрушения. Копия происходит или посредством конструктора копии или посредством operator=. Для предотвращения этой неэффективности умные компиляторы могут применить RVO или оптимизацию NRVO, но существуют случаи, в которых они не могут - несколько возвратов.

Предстоящий C++ 0x стандарт, частично доступный у гну gcc-4.3, представляет rvalue ссылку [&&], который может использоваться для различения lvalue от rvalue ссылки. Посредством этого возможно реализовать конструктора перемещения, полезного для возврата объекта, частично избегающего стоимости конструктора копии и деструктора временного файла.

Конструктор перемещения в основном что Andrei, предполагаемый несколько лет назад в статье http://www.ddj.com/database/184403855, предложенной Chris.

У конструктора перемещения есть следующая подпись:

// move constructor
object(object && obj)
{}

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

object factory()
{
    object obj;
    return std::move(obj);
}

std::move() возвращает rvalue ссылку из объекта. Наконец, что не менее важно, переместитесь, конструкторы позволяют return-by-rvalue-reference объектов non-copyable.

35
ответ дан 2 December 2019 в 03:03
поделиться

Я хотел бы добавить к превосходному ответу Nicola. Да, Вы никогда не должны возвращать повисшую ссылку (например, ссылку на локальную переменную), однако, существует три полезных способа улучшить производительность в тех случаях:

  1. Оптимизация возвращаемого значения (RVO): Вы возвращаетесь значением, но устраняете копирование при наличии только одного return оператор, который создает возвращаемое значение на месте. Вот пример RVO того, чтобы быть используемым: Как я могу маркировать строку C++?

  2. Названная оптимизация возвращаемого значения (NRVO): Вы возвращаетесь значением и объявляете переменную возвращаемого значения сначала, во главе функции. Все return возврат операторов та переменная. С компиляторами, которые поддерживают NRVO, та переменная выделяется в слоте возвращаемого значения и не становится скопированной по возврату. например,

    string
    foobar()
    {
        string result;
        // fill in "result"
        return result;
    }
    
  3. Используйте a shared_ptr и т.п. как тип возврата; это требует создавать Ваш объект на "куче", а не стек. Это предотвращает повисшие ссылочные проблемы, все еще не требуя, чтобы целый объект был скопирован, просто интеллектуальный указатель.

Между прочим, я не могу приписать себе информацию о RVO и NRVO; они прибывают прямо из Более эффективного C++ Scott Meyers. Так как у меня нет книги со мной в данный момент, любые ошибки в моем описании являются моим выполнением, не Scott.:-)

16
ответ дан 2 December 2019 в 03:03
поделиться

При возврате ссылки на переменную, которая локальна для функции затем, Вы собираетесь закончить с проблемами (в зависимости от компилятора и его настроек).

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

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

3
ответ дан 2 December 2019 в 03:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: