Что лучше: возвращать std::string по значению или по постоянной ссылке?

Вот класс с двумя геттерами с разным типом возврата:

class A {
    std::string m_test { "test" };

public:
    std::string test_by_value { return m_test; }
    const std::string& test_by_const_ref() { return m_test; }
};

// ...

Как лучше? Речь идет о std::string, а не о встроенных типах. S.T.L. говорится в https://channel9.msdn.com/Events/GoingNative/2013/Don-t-Help-the-Compiler, что лучше возвращать по значению, потому что несколько копий будут оптимизированы? Или я неправильно его понял?


person vladon    schedule 14.07.2015    source источник
comment
stackoverflow.com/questions/10231349/   -  person Cory Kramer    schedule 14.07.2015
comment
Вы хотите копию или ссылку? Это должно ответить на ваш вопрос для вас.   -  person RamblingMad    schedule 14.07.2015
comment
Лучше для чего? Дизайн? Представление? Если да, то память или время?   -  person edmz    schedule 14.07.2015
comment
1. Возврат с помощью const reference&, если объект A переживет область действия ссылки и вам нужен только для чтения. 2. Если объект A выходит за пределы области видимости и/или вам нужно его скопировать/изменить, верните value. 3. Если вам нужно изменить исходное значение return, пока оно остается в области действия, reference&. --- Не возвращайте ссылку, а затем делайте копию, чтобы изменить ее, всегда возвращайте значение для доступа на запись.   -  person CodeAngry    schedule 14.07.2015
comment
@CodeAngry Неважно знать, как остальная часть программы будет использовать его. Возврат по ссылке — лучший способ, потому что кто-то, кто использует класс, может решить использовать ссылку или сделать копию переменной.   -  person NO_NAME    schedule 14.07.2015
comment
Возможно, вы захотите принять во внимание, что вызывающий test_by_const_ref() может const_cast<> вернуть возвращенную ссылку, а затем приступить к изменению вашего (частного) m_test. Это невозможно через test_by_value().   -  person DevSolar    schedule 14.07.2015
comment
@DevSolar Если кто-то хочет испортить код, он может сделать это независимо от того, насколько вы защищены.   -  person NO_NAME    schedule 14.07.2015
comment
@NO_NAME: Это правильно, но мне также не нужно намеренно расставлять ловушки для клиента. См., например, ответ Максима. Есть очень случаи, когда я действительно хочу получить ссылку на const из геттера.   -  person DevSolar    schedule 14.07.2015


Ответы (3)


По стоимости.

Я столкнулся с подобным кодом в дикой природе:

A foo();

std::string const& x = foo().test_by_const_ref();

Бум, x — это висящая ссылка.

Этого не происходит с возвратом по значению.

person Maxim Egorushkin    schedule 14.07.2015

Ссылка правильная, вернуть string объектов по значению. NRVO позаботится о возвращении ссылок, а не за кулисами, и ваш код будет идеально семантическим и чистым, как результат.

person Blindy    schedule 14.07.2015
comment
Это означает, что ему нужна копия строки. Он может захотеть просто проверить строку. - person RamblingMad; 14.07.2015
comment
Вы неправильно читаете тогда. - person Blindy; 14.07.2015

Возврат по значению, так как компилятор оптимизирует возвращаемые значения.

person mystic_coder    schedule 14.07.2015