Подозреваю, есть простое решение, может через boost или ещё проще.
Есть примерно такой класс
class Device;
class Object
{
private:
std::unique_ptr<Device> device_{};
const float& reloadTime_; // условно, это ссылка, по которой вопрос
};
Допустим, у объекта Object в некоторый момент инициализируется переменная device_, у девайса есть время перезагрузки, которое можно из него получить методами. И, например, у него есть метод, который возвращает const-ссылку на свою внутреннюю переменную float reloadTime_;
Если бы после создания device_ я мог бы проинициализировать Object::reloadTime_, то в коде мне было бы проще обращаться к ней, чем писать каждый раз device_->GetReloadTime(); с условием, что device_ уже проинициализирован.
В случае, если device_ не создан, я могу в конструкторе reloadTime_ проинициализировать какой-то статической переменной. Но я не могу переинициализировать ссылку после создания device_.
Чего хочется:
1. Удобства в коде. Поэтому любые другие идеи приветствуются тоже!
2. Оптимизации. Но даже с GetReloadTime() проблем бы не было: компилятор туда ровно ту же ссылку на переменную Device::reloadTime_ поставит. Единственный момент тут — это проверка, что device_ не nullptr. Таких объектов как reloadTime_ может быть много, и они активно используются в логике. Хотелось бы не добавлять условия, если есть возможность это не делать.
Не очень понял из вашего описания что конкретно вам нужно, но может std::reference_wrapper вам поможет? Хотя, есть ощущение, что reloadTime_ можно было бы тупо сделать голым невладеющим указателем. Который в конструкторе Object указывал бы на какую-то глобальную переменную, а после инициализации device_ -- на что-то из device_.
Здравствуйте, so5team, Вы писали:
S>Не очень понял из вашего описания что конкретно вам нужно, но может
Я тут после публикации вопроса подумал-подумал и решил, что, пожалуй, у меня косяки в архитектуре
Странно, как минимум, часто использовать внутреннюю переменную из Device в Object. Если такие проверки действительно нужны — их надо попробовать перенести в Device, а классу-хозяину передавать туда нужную для сравнения информацию. И тогда device_->GetReloadTime() (даже с проверкой) должно быть достаточно. Можно даже избежать проверки через тот же optional или reference_wrapper
Если Object так сильно связан по данным с Device — логично как-то объединить/распилить эти классы в иерархии (в некий средний класс) чтобы вся информация по процессу была под одним капотом.
Здравствуйте, CEMb, Вы писали:
R>>можно std::optional<float> reloadTime_ R>>ну или вместо ссылки указатель юзайте
CEM>Интересный вариант, спасибо! CEM>Указатель — не совсем удобно, его на nullptr проверять надо.
std::optional — это не про удобство. И там тоже надо проверять на has_value(). А ты как хотел?
А указатель можно не проверять, если ты гарантируешь, что он не будет нулевым, а пользовательский код не может его поменять (не, ну если задаться целью, конечно всё может быть, но это вылезет сразу)
кажется понимаю
вы хотите что бы ссылка была всегда валидна
какие бы способы не выбирали
все равно нужно будет трекать а валидно ли, будь то std::optional или указатель
а referrence_wrapper вообще в вашем случае опасно
поскольку он может разименоваться при обращении в нулл до создания объекта
если там не float а что то тяжелое
то придумайте что то типа std::optional<std::reference_wrapper<BIG_OBJECT>>
Здравствуйте, CEMb, Вы писали:
CEM>Тема про realtime и быстродействие. CEM>
CEM>class Device;
CEM>class Object
CEM>{
CEM>private:
CEM> std::unique_ptr<Device> device_{};
CEM> const float& reloadTime_; // условно, это ссылка, по которой вопрос
CEM>};
CEM>
CEM>Допустим, у объекта Object в некоторый момент инициализируется переменная device_, у девайса есть время перезагрузки, которое можно из него получить методами. И, например, у него есть метод, который возвращает const-ссылку на свою внутреннюю переменную float reloadTime_;
Тут ссылка не нужна. Если рассматривать reloadTime_ как кэш значение, то всё просто — при инициализации device_ инициализируете reloadTime_. Чтобы выразить константность для доступа можно добавить приватный метод inline float GetReloadTime() const и нигде не обращаться за значением напрямую.
Если умеете пользоваться assert (не забываете про #define NDEBUG ) то что-то вроде:
CEM>class Device;
CEM>class Object
CEM>{
CEM>private:
CEM> std::unique_ptr<Device> device_{};
CEM> const float& reloadTime_; // условно, это ссылка, по которой вопрос
CEM>};
CEM>
CEM>Чего хочется: CEM>1. Удобства в коде. Поэтому любые другие идеи приветствуются тоже! CEM>2. Оптимизации. Но даже с GetReloadTime() проблем бы не было: компилятор туда ровно ту же ссылку на переменную Device::reloadTime_ поставит. Единственный момент тут — это проверка, что device_ не nullptr. Таких объектов как reloadTime_ может быть много, и они активно используются в логике. Хотелось бы не добавлять условия, если есть возможность это не делать.
Я не совсем понимаю, каким образом эта ссылка избавляет от проверок device_ на nullptr. Ведь когда заканчивается вермя жизни объекта device, ссылка тут же становится невалидной. А если устройство класса Object гарантирует, что время жизни объекта Object не превышает время жизни объекта Device, то проверки на nullptr достаточно только одной — в конструкторе класса Object.
Приватная фунция-член вместо ссылки — не вариант?
class Device;
class Object
{
private:
std::unique_ptr<Device> device_{};
float reloadTime() const {
assert(device_);
return device_->GetReloadTime();
}
};
И в коде потом используешь reloadTime() вместо reloadTime_;
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, CEMb, Вы писали:
CEM>Указатель — не совсем удобно, его на nullptr проверять надо.
Сейчас опять набегут критики, но таки надо подчеркнуть, что необходимость проверять указатель на nullptr возникает лишь в случае, когда логика программы допускает такое значение. Если же по логике этого не допускается, то технически (на уровне двоичного кода) работа и с указателем, и со ссылкой организуется одинаково. Даже если какой-то компилятор умеет в отладочном режиме автоматически проверять ссылку перед ее использованием, он так же может уметь проверять и указатель перед разыменованием.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Сейчас опять набегут критики, но таки надо подчеркнуть, что необходимость проверять указатель на nullptr возникает лишь в случае, когда логика программы допускает такое значение.
Здравствуйте, Евгений Музыченко, Вы писали:
R>>Мы помним, помним — указатель нужно разыменовывать без проверки, а на nullptr проверять потом ссылку: https://rsdn.org/forum/cpp/8499561.1
Здравствуйте, reversecode, Вы писали:
R>джентельмены R>не оскверняйте тему R>предлагаю вам начать на шпагах R>продолжить на мечах R>и закончить на пистолетах
Ты миротворец или подстрекатель? Не пойму что-то.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Какая еще память, выдумщик?
Ваша, которая в мозгу. Вместе с теми зонами, что отвечают за восприятие смысла.
R>Я же ссылку привел на твое утверждение. Эх, никак ты не привыкнешь, что все слова здесь записываются.
Так в том и дело, что записанные слова не соответствуют тому смыслу, с каким Вы их пересказали.
Я понимаю, что очень чешется желание быть язвительным, но надо ж пытаться держать себя в руках.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>>Или память подводит, или передергинг детектед. ЕМ>>Ваша, которая в мозгу. Вместе с теми зонами, что отвечают за восприятие смысла.
ЕМ>Я понимаю, что очень чешется желание быть язвительным, но надо ж пытаться держать себя в руках.
Ну, по крайней мере, это не я тебе диагнозы по интернету тут ставлю. Так кому из нас хочется быть язвительным? Мне кажется, или ты пытаешься спроецировать свое эмоциональное состояние на меня?
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, CEMb, Вы писали:
CEM>2. Оптимизации. Но даже с GetReloadTime() проблем бы не было: компилятор туда ровно ту же ссылку на переменную Device::reloadTime_ поставит. Единственный момент тут — это проверка, что device_ не nullptr. Таких объектов как reloadTime_ может быть много, и они активно используются в логике. Хотелось бы не добавлять условия, если есть возможность это не делать.
Преждевременная оптимизация, или есть документальное подтверждение, что такая проверка вызовер проблемы с производительностью? Целевая платформа не умеет делать предсказание ветвлений?