Один из способов сделать это - получить строку
std::string name;
Как элемент данных вашего объекта. А затем, в функции unleashMonkeyFish создайте строку, как вы это сделали, и передайте ее по ссылке , как вы показали
void setName( const std::string & parameter_name ) {
name = parameter_name;
}
Он будет делать то, что вы хотите - создать одну копию, чтобы скопировать строку в ваш элемент данных. Это не значит, что он должен перераспределять новый буфер внутри, если вы назначаете другую строку. Возможно, назначение новой строки просто копирует несколько байтов. std :: string имеет возможность резервировать байты. Таким образом, вы можете вызвать «name.reserve (25);» в вашем конструкторе, и он, скорее всего, не будет перераспределен, если вы назначите что-то меньшее. (Я провел тесты, и похоже, что GCC всегда перераспределяет, если вы присваиваете из другой std :: string, но не если вы присваиваете из c-строки. Они говорят, у них есть копия при записи строка, которая объясняет это поведение).
Строка, которую вы создаете в функции unleashMonkeyFish, автоматически высвобождает выделенные ей ресурсы. Это ключевая особенность этих объектов - они сами управляют своими вещами. Классы имеют деструктор, который они используют для освобождения выделенных ресурсов после того, как объекты умирают, также есть и std :: string. На мой взгляд, вам не стоит беспокоиться о том, чтобы этот std :: string был локальным в функции. Это, скорее всего, не сделает ничего заметного для вашей работы. Некоторые реализации std :: string (msvc ++ afaik) имеют оптимизацию с небольшим буфером: до некоторого небольшого предела они сохраняют символы во встроенном буфере вместо выделения из кучи.
Редактировать :
Как оказалось, есть лучший способ сделать это для классов, которые имеют эффективную swap
реализацию (постоянное время):
void setName(std::string parameter_name) {
name.swap(parameter_name);
}
Причина, по которой это лучше, заключается в том, что теперь вызывающая сторона знает, что аргумент копируется. Оптимизация возвращаемого значения и аналогичные оптимизации теперь могут легко применяться компилятором. Рассмотрим этот случай, например
obj.setName("Mr. " + things.getName());
Если бы вы взяли ссылку setName
, тогда созданный в аргументе временный объект будет привязан к этой ссылке, а в setName
он будет скопирован, а после возврата временный объект будет уничтожен - что В любом случае, это был одноразовый продукт. Это только неоптимально, поскольку вместо его копии можно было бы использовать сам временный. Если параметр не является ссылкой, то вызывающий объект увидит, что аргумент все равно копируется, и значительно упростит работу оптимизатора - потому что ему не нужно будет вставлять вызов, чтобы увидеть, что аргумент копируется в любом случае.
Для дальнейшего объяснения прочитайте отличную статью BoostCon09/Rvalue-References