Можно ли вернуть ссылку из чисто виртуальной функции? - PullRequest
2 голосов
/ 24 июня 2011
class I {
public:
  virtual std::wstring const& GetName() const = 0;
};

Обычно клиенты, которые реализуют этот интерфейс, содержат свое имя внутри своего тела.И все работает просто отлично.Но иногда результат GetName вычисляется во время выполнения функции.Использование статической переменной для хранения результата не очень хорошая идея.Но возврат по значению требует дополнительных издержек производительности.

Так как же решить эту проблему?Спасибо.

Ответы [ 5 ]

4 голосов
/ 24 июня 2011

Но для возврата по значению требуются дополнительные потери производительности.

Это не так.Компилятор очень часто сможет удалить копию, используя Оптимизация возвращаемого значения .

0 голосов
/ 24 июня 2011

Хотя все остальные, похоже, согласны с тем, что это очень плохая идея (по разным причинам, все из которых несколько правдивы), я не вижу ничего принципиально неправильного в возврате string const&.

Делая так

  • технически легитимен и будет работать просто отлично (он просто устанавливает «контракт», который производные классы должны выполнить каким-то еще неуказанным способом)
  • , вероятно, является незначительной микрооптимизацией (которая также, вероятно, ничем не отличается от RVO в оптимизированной сборке), но это также не повредит ... поскольку,
  • не позволяет вызывающему абоненту изменять имя, что имеет смысл (вызывающий не компетентен, поэтому он должен был спросить в первую очередь!) - это семантически на самом деле хорошая вещь
  • будет работать независимо от фактической пока неизвестной реализации, даже с временными (поскольку для const ссылок стандарт продлевает время жизни локальных переменных до времени жизни ссылки)

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

0 голосов
/ 24 июня 2011

ОК, в каком смысле?Это законно C ++.Обычно это очень плохая практика программирования по той причине, о которой вы упоминаете: она накладывает (обычно) ненужное ограничение на производные классы.Независимо от virtual, вы должны возвращать ссылку только тогда, когда семантика функции требует этого;если тип имеет семантику значений, например std::string, то это будет только неконстантная ссылка.(Шаблоны несколько усложняют проблему, и для таких классов, как std::vector, разумно возвращать ссылку на const из operator[] const.)

0 голосов
/ 24 июня 2011

Кажется, это плохая идея.Если накладные расходы действительно имеют значение, вы можете использовать некоторый контейнер строк с неявным разделением (семантика копирования при записи), например QString.

0 голосов
/ 24 июня 2011

Не догадывайтесь о проблемах производительности: хотя люди часто возвращают std::string по константной ссылке, возвращать их по значению не составляет особого труда, особенно если у вас нет другого выбора.

На самом деле, иногда вы можете даже изменить это последнее, поскольку это влияет только на несколько вещей для клиентского кода.

Помните: преждевременная оптимизация - корень всего зла.

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

Если некоторый производный класс должен выполнить дорогостоящие вычисления, он все равно может сохранить результат в элементе std::wstring и вернуть ссылку на него. Но, опять же, не угадывайте проблемы с производительностью: сначала оцените и сосредоточьтесь на этом, только если это кажется узким местом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...