C ++ 11 — C ++ Передача длинной строки конструктору или установщику

У меня есть класс с членом Glib :: ustring (если вы не знакомы с ним, предположите, что это std :: string), который, как ожидается, будет содержать длинную строку, т. Е. Как минимум один абзац, может быть, еще несколько. Может быть, даже более 10 пунктов. Строка планируется отображать в графическом интерфейсе, поэтому, возможно, в будущем она будет сохранена в буфере текстового виджета, но пока это просто объект-член строки моего класса C ++.

Вопрос в том, как передать строку в конструктор и как передать ее в метод set_string (). Длинная строка означает большую копию, поэтому хорошим решением было бы взять ссылку на rvalue и std :: переместить аргумент в объект-член. Но я также не хочу, чтобы интерфейс класса был удивительным и сложным в использовании / понимании. Вы знаете, правило наименьшего удивления.

Вот я и подумал, каково ожидаемое / общее решение в этом случае?

(для метода сеттера есть еще один вариант: поскольку редактирование выполняется в графическом интерфейсе, просто позвольте графическому интерфейсу редактировать строку напрямую, и тогда единственное использование метода сеттера — полностью заменить строку программно, например, сбросить ее или отменить недавнее редактирование )

class MyClass
{
public:
explicit MyClass (Glib::ustring str);
void set_string (Glib::ustring str);
private:
Glib::ustring str;
}

(Я видел код существующих библиотек, например, gtkmm, принимающий строки по константной ссылке, но я также видел сообщения SO с ответами, в которых говорилось о передаче по значению для оптимизации)

0

Решение

http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

Ваша функция должна принять string по значению, предполагая, что ваш string имеет эффективный Move-конструктор.

Когда вы ожидаете, что строка будет длинной, вызывающая сторона вызывает std::move и передает значение установщику / конструктору. Это не удивительно, потому что std::move довольно ясно показывает, что вы перемещаете данные.

Если ваша система имеет не более чем скромное количество параллелизма, и вы редко изменяете строки (на самом деле, большинство строк разделяются гораздо больше, чем модифицируются), общие указатели на неизменяемые строки на самом деле довольно полезный шаблон. (Совместно используемые данные записи — это число ссылок, поэтому при высоком уровне параллелизма может возникнуть конфликт)

4

Другие решения

Я бы пошел за ссылками (не только передавая их, но и сохраняя ссылку). Тем не менее, сеттер должен переустановить ссылку, что невозможно. Если вам действительно нужно изменить строку после построения, вы должны использовать указатели (возможно, умные указатели).

В зависимости от окружающего кода вы можете использовать общее владение строкой. В этом случае я бы использовал std::shared_pointer<GLib::ustring>, Если вам нужен сеттер. (В противном случае, ссылка лучше.)

Обратите внимание, что «некоторые абзацы» не являются очень длинный строки. В пользовательских интерфейсах задержка в пару миллисекунд, скажем, при загрузке какого-либо текстового файла, вполне допустима. Как всегда: пожалуйста, сначала профилируйте свой код, определите узкое место, затем оптимизируйте, если вам нужно, чтобы он был быстрее.

1

По вопросам рекламы [email protected]