Какой эффективный в памяти способ передать строку в качестве аргумента функции.? - PullRequest
5 голосов
/ 19 октября 2011

любой может сказать мне. Есть ли какая-либо выгода передачи строки как func (string &) вместо func (string).

Ответы [ 8 ]

4 голосов
/ 19 октября 2011

Передача объекта по ссылке означает, хорошо, что вы передаете ссылку по значению, а не объект по значению, что означает, что вы должны сделатькопировать при вызове функции.

Однако, передача по ссылке вводит новый набор вопросов, о которых вы должны знать:

  1. - изменяет ли функция переданный объект или нет?Если это не так, вы должны добавить модификатор const
  2. . Нужно ли функции изменять объект, но не подвергать изменениям вне границ функции?В этом случае вам действительно нужна копия.
  3. хранит ли функция где-то / каким-то образом ссылку на переданный объект?В этом случае вы должны понимать, как передается владение объектом и когда его можно безопасно удалить.Возможно, вы захотите использовать умные указатели для решения этих проблем

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

4 голосов
/ 19 октября 2011

func(string &) передает строку по ссылке. Это означает, что он не будет скопирован и что функция может его изменить.

func(string) передает строку по значению. Это означает, что будет создана копия, и что функция может изменять только свою собственную локальную копию этой строки.

Чтобы передать строку без копирования, но предотвратить ее изменение, используйте func(const string&).

Если ваша функция все равно должна получить копию аргумента, передача по значению предпочтительнее.

2 голосов
/ 19 октября 2011

Передача ссылки обычно будет более эффективной для сложных типов, но это должна быть ссылка на const, если вы не хотите, чтобы функция могла изменять ее:

void f(string);        // function gets its own copy - copying may be expensive
void f(string&);       // function can modify the caller's string
void f(string const&); // function can read the caller's string, but not modify it
1 голос
/ 19 октября 2011

Когда вы передаете его как string, строка сначала копируется, и копия отправляется в функцию.Лучший способ передать дорогие объекты, такие как строки, если вы не хотите, чтобы функция их изменяла, - это const string&.

. const важно.Прежде всего, это гарантирует, что строка не будет изменена внутри функции.Кроме того, вы не сможете передать литерал в функцию без его использования func("this is a litearal because it isn't inside a variable").

1 голос
/ 19 октября 2011

Вы также можете использовать func(const string& ) вместо func(string& ), чтобы убедиться, что параметр переданной ссылки не будет ошибочно изменен внутри функции.

0 голосов
/ 19 октября 2011

Вы также можете попробовать использовать RValue эталонные оптимизацию с помощью перемещения семантики.

void func(string &&s)
{
    myS = std::move(s);
}
0 голосов
/ 19 октября 2011

Да.Передача ссылки всегда эффективна.
Строка может быть сохранена по значению, и копирование может занять до O (n) (т. Е. Копирование занимает время, пропорциональное длине строки).Это также приведет к выделению динамической памяти, которая обычно намного дороже, чем копия.
Вы также можете рассмотреть возможность передачи по ссылке на const, например, func (const string &), чтобы избежать любых непреднамеренных изменений.

0 голосов
/ 19 октября 2011

Передача по ссылке, как правило, лучше, чем передача по значению, если речь идет о производительности (за исключением встроенных типов данных). Так что да, func(string&) лучше, чем func(string). При условии, что переданный string может быть изменен после завершения функции. Если вы не собираетесь менять string, используйте func(const string&).

С другой стороны, я помню, что где-то читал, что в STL оптимизированы string. Означает, что если вы передаете string по значению, это может не обязательно создавать новую строку в куче. Таким образом, передача по стоимости может оказаться не такой уж дорогой, как вы ожидаете. например,

string s1 = "hello";  // new buffer allocated on heap and copied "hello"
string s2 = s1;  // s2 and s1 both 'may' refer to same heap 
...
s1 += " world"; // s2 continue referring to old heap ...
                // new heap created to accomodate "hello world" referred by s1
...