Лучше возвратить ссылку C++ или weak_ptr?

Ну, не видя твой код, мне не о чем продолжать, но, возможно, ты неправильно устанавливаешь состояние. Еще нужно учесть, что this.setState({}) происходит не сразу, а на самом деле асинхронно. Итак, если вы попытаетесь получить доступ к состоянию до того, как оно будет установлено, вы получите старые данные. Вы можете предоставить функцию обратного вызова в качестве второго аргумента для запуска после установки состояния:

const callback = () => {
    console.log(this.state.players);
}

this.setState({
    players: newPlayers
}, callback);
12
задан Doug T. 18 October 2008 в 18:39
поделиться

9 ответов

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

1
ответ дан 2 December 2019 в 06:28
поделиться

Почему бы не возвратить a shared_ptr<>? Thatway, который клиент получает для использования то, что возвращается столько, сколько ему нужен он, но нет никакой проблемы, если класс 'сервера' уходит.

Нет слишком многих ситуаций где семантика weak_ptr<> имейте большой смысл (кэши и???). Обычно, когда клиент просит что-то, это хочет иметь владение той вещи, определенной клиентом самой (и совместно использованное владение так же хорошо как полное владение).

Если у Вас есть ситуация, где объект 'сервера' может быть уничтожен без ведома клиента (ситуация, где Вы могли бы хотеть use weak_ptr<> или shared_ptr<>) о худшей вещи можно сделать, возвратить ссылку на участника. В этом случае клиент не может знать, безопасно ли получить доступ к возвращенной ссылке. Необходимо возвратить копию участника или интеллектуального указателя, который может правильно управлять временем жизни возвращаемого участника.

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

13
ответ дан 2 December 2019 в 06:28
поделиться

Необходимо постараться не отдавать внутренности; это - инструкция n. 42 "стандартов кодирования C++" (Herb Sutter и Andrei Alexandrescu). Если по некоторым причинам Вы имеете к, лучше для возврата ссылки константы и не указателя, потому что constness не распространяет через него.

weak_ptr <>, кажется, эффективное решение, даже если его основная цель состоит в том, чтобы избежать циклов shared_ptr. Вместо этого при возврате shared_ptr <>, Вы расширяете жизнь такого внутреннего, которое в большинстве случаев не имеет смысла.

Проблема с экземпляром, который уходит, в то время как кто-то обрабатывает ссылку на ее внутренности, должна столкнуться с корректной синхронизацией/коммуникацией между потоками.

4
ответ дан 2 December 2019 в 06:28
поделиться

Почему возврат слабый указатель? Я думаю, что Вы делаете это более сложным без необходимого преимущества.

1
ответ дан 2 December 2019 в 06:28
поделиться

Я думаю, что единственный разумный ответ, он зависит от того, как участник связан с Классом, и что Вы хотите, чтобы пользователи Класса смогли сделать. Делает _member имейте значимое существование, которое независимо от Объекта класса? Если это не делает, то я не думаю с помощью a shared_ptr поскольку это имеет любой смысл, возвращаете ли Вы a weak_ptr или a shared_ptr. По существу любой предоставил бы пользовательский доступ к членскому объекту, который мог пережить Объект класса, который дает ему значение. Это могло бы предотвратить катастрофический отказ, но за счет сокрытия серьезной ошибки дизайна.

Как awgn указывает, необходимо быть очень осторожны относительно представления внутренностей класса. Но я думаю там, определенно место для него. Например, у меня есть класс в моем коде, который представляет объект файла, состоявший из объекта заголовка файла и объекта данных файла. Полностью дублирование интерфейса заголовка в классе файла было бы глупо и нарушило бы DRY. Вы, я предполагаю, могли вынудить пользователя получить копию объекта заголовка, внести изменения в копию и затем скопировать внешний объект назад в полный класс файла. Но это представляет большую неэффективность, которая только покупает Вас способность сделать объектное представление файла из заголовка отличающимся, чем объектное представление заголовка. Если Вы уверены, что это не что-то, что Вы собираетесь хотеть сделать, Вы могли бы также возвратить ссылку неконстанты на заголовок - это более просто и более эффективно.

2
ответ дан 2 December 2019 в 06:28
поделиться

Я хочу поднять что-то в ответ на комментарии (от OP и Colomon, главным образом) об эффективности и т.д. Часто времена копируя материал вокруг действительно не имеют значения, с точки зрения реальной производительности.

Я записал программы, которые делают большое защитное копирование. Это - идиома в Java, где, потому что все объекты передаются указателем, существует большое искажение продолжения, таким образом, Вы копируете что-либо собирающееся в Ваш класс повредить искажение, удостоверяясь, что клиенты Вашего класса не могут нарушить Ваши инварианты класса путем изменения объекта после факта.

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


ETA: Я чувствую потребность прояснить мысль моего сообщения, так как один комментатор считал его по-другому по сравнению с тем, как я предназначил, и вполне возможно другие сделали также. Моя точка не то, что это должно хорошо скопировать материал вокруг волей-неволей; а скорее, нужно всегда представлять производительность их кода, а не предполагать дико то, как это будет работать.

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

4
ответ дан 2 December 2019 в 06:28
поделиться

Моя основная, неосведомленная инструкция:

Я понимаю, что последний может быть небезопасным, если экземпляр ClassWithCppReference может уйти, в то время как у кого-то все еще есть ссылка на участника. Однако я могу также видеть аргумент в пользу последнего класса с типами POD, теми, которые говорят, сообщение к устройству, и Вы не хотели копировать участника все время.

0
ответ дан 2 December 2019 в 06:28
поделиться

В зависимости от контекста любой мог быть прекрасным. Основная проблема с возвратом 'живой' ссылки на участника (если необходимо выставить тот во-первых) состоит в том, что, кто бы ни использует подвергнутого участника, то, что клиент мог бы держать на него дольше, чем содержание объекта существует. И если Ваши клиентские доступы сказали, что участник через ссылку, когда ее содержание объекта выходит из объема, Вы будете сталкиваться с 'нечетными' катастрофическими отказами, неправильно значения и подобная забава.Не рекомендуется.

Возврат weak_ptr <> имеет главное преимущество, которое он смог бы передать клиенту, что объекта, они пробуют доступ, не стало, который не может сделать ссылка.

Моя ценность за 2 пенса была бы:

  • Если бы ни один из Ваших клиентов никогда не использовал бы участника, Вы, поскольку автор является единственным человеком, чтобы использовать его и управлять объектным временем жизни, возвращение ссылки прекрасно. Ссылка константы была бы еще лучше, но это не всегда возможно в реальном мире с существующим кодом.
  • Если кто-либо еще получил бы доступ и использовал бы участника, особенно если Вы пишете библиотеку, возвратите weak_ptr <>. Это сохранит Вас много горя и сделает отладку легче.
  • Я не возвратил бы shared_ptr <>. Я видел этот подход, и он обычно одобряется людьми, которые чувствуют себя неловко из-за понятия weak_ptr/weak ссылки. Основная оборотная сторона, которую я вижу с ним, - то, что это искусственно расширит время жизни участника другого объекта вне объема его содержания объекта. Это концептуально неправильно в 99% случаев и хуже, может повернуть Вашу программную ошибку (получающий доступ к чему-то, что не является там больше) в концептуальную ошибку (получающий доступ к чему-то, чем, который не должен быть там больше).
-1
ответ дан 2 December 2019 в 06:28
поделиться

В большинстве ситуаций я бы предоставил

const Member& GetMember() const;
Member& GetMember(); // ideally, only if clients can modify it without
                     // breaking any invariants of the Class

weak_ptr< Member > GetMemberWptr(); // only if there is a specific need
                                    // for holding a weak pointer.

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

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

0
ответ дан 2 December 2019 в 06:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: