Здравствуйте, Андрей Е, Вы писали:
АЕ>В класс передается по ссылке или указателю некий объект(например файл), и затем ссылка или указатель сохраняется внутри, как член данных. И класс затем будет этот объект изменять(например записывать данные в файл). Объект передается в конструкторе, так что его можно передавать и хранить как по ссылке так и по указателю. В первом приближении вроде корректно работает и тот и тот вариант.
АЕ>С одной стороны, вроде есть рекомендация, что если явно не нужны указатели, то следует использовать ссылки. АЕ>С другой стороны, в книге "Стандарты программирования на C++" в совете 52, в самом конце утверждается, что наличие члена-ссылки почти наверняка является ошибкой.
АЕ>Подскажите, пожалуйста, что предпочесть, ссылку или указатель?
Используя ссылки, можно достигнуть такого уровня контроля, который невозможен при указателях.
Например, вы не сможете забыть проинициализировать ссылочный член класса, не присвоете ему
ноль или недопустимое значение, не вызовете delete раньше времени.
Не менее важно то, что объекты, которыми инициализируются ссылочные типы-члены, имеют явно
определенное время жизни и должны быть сконструированы до инициализации включающего класса.
Соответственно, они будут разрушаться в обратном порядке, то есть проблема "висячих ссылок" в
большинстве случаев снимается.
Лично я стремлюсь использовать ссылки везде, где можно.
Только когда это невозможно физически или явно нежелательно, возвращаюсь к указателям.
Здравствуйте, Андрей Е, Вы писали:
АЕ>Подскажите, пожалуйста, что предпочесть, ссылку или указатель?
Я использую ссылку, как член класса только тогда, когда экземпляры этого класса будут создаваться исключительно на стеке. В остальных случаях (за редким исключением) смарт указатели.
Здравствуйте, okman, Вы писали:
O>Использование умных указателей, особенно когда речь идет про подсчет ссылок, связано с накладными O>расходами — на копирование, на доступ к хранимому объекту (разыменование), плюс затраты на содержание. O>Для каких-то сценариев этот подход оправдан, для других не подходит совершенно.
Э-э-э, если у тебя есть выбор указатель/умный указатель, то, как бы, всё в твоих руках.
В конце концов ты можешь просто сделать "умный указатель" который всего-то инициализируется в конструкторе по умолчанию нулём, и при этом не даёт вызывать -> если он ещё 0, напрмер. Скажем кидает исключение, или у него стоит assert( p != 0 ).
В любом случае ты можешь
1) Выбрать стратегию под задачу, а не морочиться с какими-то предустановками навязанными ссылками.
2) Легко поменять стратегию позже, когда выяснится, что выбор не совсем удачен
3) В любом случае, если речь идёт о развесистом дереве объектов со связями там и много чем ещё, то часто накладные расходы на умные указатели не самве дороги енакладные расходы в этой структуре данных.
Ну и вообще, уход от накладных расходов заранее -- это часто та самая преждевременная оптимизация
Лично я считаю правильной парадигму такую, что ПО УМОЛЧАНИЮ умный указатель, а если есть ВЕСКИЕ причины, то ДРУГОЙ УМНЫЙ УКАЗАТЕЛЬ, и только в случае КРАЙНЕ ВЕСКИХ ПРИЧИН просто указатель. А ссылка всегда должна быть автоматической и при её использовании мы должны предполагать, что на автоматическую переменную при этом...
O>И потом, одни проблемы снимаются, а им на смену приходят другие — например, смартпоинтеры не O>получится использовать полиморфно, и если сконструировать умный указатель локально, а затем вернуть из
Это от смартпоинтера зависит, однако...
Некоторые очень даже можно...
O>функции его внутренний объект, никто не выдаст даже предупреждения, что, в общем-то, можно понять.
Тоже от смартпоинтера зависит. В целом удобнее пользоваться смартпоинтерами такими, что явно указатель у них можно получить только вызовом ЯВНОГО метода. Тогда ошибки такого рода, как ты описал случайно не посадишь....
O>В отличие от его менее интеллектуальных аналогов, умный указатель небезопасно использовать в O>многопоточном окружении, и я даже не упомянул о циклических зависимостях, путь это и очень редкое явление.
Опять же, всё зависит от конкретной реализации конкретного умного указателя. Они бывают разными, вообще-то
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, igna, Вы писали:
I>А где тут глубокий смысл использования указателя вместо ссылки?
Ну поле может быть любым умным или не очень умным указателем...
I>Напомню, ты предложил по умолчанию использовать умные указатели, и только если есть веские причины, то указатели обычные. Ссылкам места вообще не оставил,
В качестве полей!
I>вот я и привел пример со ссылкой, и спрашиваю, что мы выиграем, если заменим ссылку на указатель в следующем примере?:
I>
1) Мне не нравится в этом примере то, что требуется чтобы либо writer был автоматическим объектом, либо аргумент его конструктора должен быть статическим объектом, либо надо как-то ещё гарантировать, что writer переживёт свой поток вывода.
При этом в некоторых компиляторах, параметр может указывать вообще на временный объект!
Так что чревато это ошибками.
Это что касается параметра конструктора. Лично мне вариант с указателем на поток, передаваемым в конструктор, кажется намного более надёжным, хотя и более кондовым, конечно.
Что касается поля, то, например, мы выиграем возможность в любой момент перейти к shared_ptr, скажем, без изенений в остальном коде writer...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Члены данных: что лучше ссылка или указатель?
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>ну если указываемые объекты будут умирать после объектов содержащих ссылки или указатели на них то какая разница ссылка или указатель ?
Разница обнаружится при сопровождении, например. Ссылки вынуждают клиентов выполнять
проектные решения, а программист, который сделает что-то не так, сразу же получит ошибку компиляции.
J>а если наоборот то никакой ссылкой не предотвратить преждевременной умирание указываемых объектов.
Такое возможно, только если используется ссылка на указатель. Или, если сильно поднапрячься,
можно подобрать решение, используя помощью reinterpret_cast/union_cast/offsetof/__asm и т.п.
J>я это все к тому что это должен учитывать алгоритм а не ссылки vs указатели разве нет ?
Это да, но при прочих равных условиях ссылка предпочтительнее, на мой взгляд.
Здравствуйте, Андрей Е, Вы писали:
АЕ>Подскажите, пожалуйста, что предпочесть, ссылку или указатель?
Умный указатель! Так как ситуация "несколько автоматических объектов ссылаются друг на друга" -- это очень частный случай взаимосвязанных объектов.
Поэтому по умолчанию, связь объектов должна выражаться умными указателями. И только если есть какие-то веские причины к тому, то умные указатели можно заменить обычными. Почему тогда именно указателями, а не ссылками? Да потому, что умных ссылок в С++ не бывает (точку перегрузить нельзя)...
Тут ещё есть один аспект небольшой. АЕ>В класс передается по ссылке или указателю некий объект(например файл), и затем ссылка или указатель сохраняется внутри, как член данных.
Так делать, IMHO, нехорошо. Особенно если ссылка константная. Константная ссылка очень легко может оказаться ссылкой на какой-то временный объект...
IMHO, конечно же, но лучше бы, если мы кому-то что-то отдаём во владение или в совместное пользование, то передавать ему указатель (не важно умный или нет), но ЯВНО. А по ссылке лучше передавать именно ЗНАЧЕНИЯ, но не УНИКАЛЬНЫЕ ОБЪЕКТЫ, предназначенные ДЛЯ ДАЛЬНЕЙШЕГО ИСПОЛЬЗОВАНИЯ...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Члены данных: что лучше ссылка или указатель?
Здравствуйте, LaptevVV, Вы писали:
LVV>Ссылка — не является переменной. Поэтому в качестве поля не будет полноценным полем. Указатель — переменная, которая может менять свои значения.
Все верно, только зачем давать полю возможности, которые не будут использоваться? Так можно и против const возражать.
Здравствуйте, Андрей Е, Вы писали:
АЕ>В класс передается по ссылке или указателю некий объект(например файл), и затем ссылка или указатель сохраняется внутри, как член данных. И класс затем будет этот объект изменять(например записывать данные в файл). Объект передается в конструкторе, так что его можно передавать и хранить как по ссылке так и по указателю. В первом приближении вроде корректно работает и тот и тот вариант.
АЕ>С одной стороны, вроде есть рекомендация, что если явно не нужны указатели, то следует использовать ссылки. АЕ>С другой стороны, в книге "Стандарты программирования на C++" в совете 52, в самом конце утверждается, что наличие члена-ссылки почти наверняка является ошибкой.
АЕ>Подскажите, пожалуйста, что предпочесть, ссылку или указатель?
Сугубое ИМХО.
Ссылка — не является переменной. Поэтому в качестве поля не будет полноценным полем. Указатель — переменная, которая может менять свои значения.
Лично я ссылки использую практически только для передачи параметров и возврата результатов (причем, обычно только при перегрузке операций). А если мне нужно поле в классе, использую исключительно либо объект, либо указатель на объект.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Члены данных: что лучше ссылка или указатель?
Здравствуйте, Erop, Вы писали:
АЕ>>Подскажите, пожалуйста, что предпочесть, ссылку или указатель?
E>Умный указатель!
Использование умных указателей, особенно когда речь идет про подсчет ссылок, связано с накладными
расходами — на копирование, на доступ к хранимому объекту (разыменование), плюс затраты на содержание.
Для каких-то сценариев этот подход оправдан, для других не подходит совершенно.
И потом, одни проблемы снимаются, а им на смену приходят другие — например, смартпоинтеры не
получится использовать полиморфно, и если сконструировать умный указатель локально, а затем вернуть из
функции его внутренний объект, никто не выдаст даже предупреждения, что, в общем-то, можно понять.
В отличие от его менее интеллектуальных аналогов, умный указатель небезопасно использовать в
многопоточном окружении, и я даже не упомянул о циклических зависимостях, путь это и очень редкое явление.
В класс передается по ссылке или указателю некий объект(например файл), и затем ссылка или указатель сохраняется внутри, как член данных. И класс затем будет этот объект изменять(например записывать данные в файл). Объект передается в конструкторе, так что его можно передавать и хранить как по ссылке так и по указателю. В первом приближении вроде корректно работает и тот и тот вариант.
С одной стороны, вроде есть рекомендация, что если явно не нужны указатели, то следует использовать ссылки.
С другой стороны, в книге "Стандарты программирования на C++" в совете 52, в самом конце утверждается, что наличие члена-ссылки почти наверняка является ошибкой.
Подскажите, пожалуйста, что предпочесть, ссылку или указатель?
Здравствуйте, Андрей Е, Вы писали:
АЕ>Подскажите, пожалуйста, что предпочесть, ссылку или указатель?
Для начала отвлечемся от того, что это поле класса и поставим общий вопрос: когда использовать ссылку, а когда указатель. Этот вопрос вызывает жаркие споры. Я знаю как минимум 3 правила на эту тему. Поэтому я бы советовал определиться с данным правилом, чтобы применять его при написании всей программы, а про поле класса получится частный случай, скорее всего.
P.S. Наверно не очень помог, но вопрос в реальности не такой однозначный. Посмотрим на ответы других.
Здравствуйте, Андрей Е, Вы писали:
АЕ>В класс передается по ссылке или указателю некий объект(например файл), и затем ссылка или указатель сохраняется внутри, как член данных. И класс затем будет этот объект изменять(например записывать данные в файл). Объект передается в конструкторе, так что его можно передавать и хранить как по ссылке так и по указателю. В первом приближении вроде корректно работает и тот и тот вариант.
АЕ>С одной стороны, вроде есть рекомендация, что если явно не нужны указатели, то следует использовать ссылки. АЕ>С другой стороны, в книге "Стандарты программирования на C++" в совете 52, в самом конце утверждается, что наличие члена-ссылки почти наверняка является ошибкой.
АЕ>Подскажите, пожалуйста, что предпочесть, ссылку или указатель?
в плане эргономики выигрывает ссылка
вместо subj->member можно просто subj.member на 1 символ короче
вместо *subj = value можно просто subj = value весь плюс ссылок
в авторазыменовании в перегруженных операторах без них никак
сильно ленивому человеку удобнее ссылки меньше символов набирать
Re[2]: Члены данных: что лучше ссылка или указатель?
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>Здравствуйте, LaptevVV, Вы писали:
J>
J>Ссылка — не является переменной. Поэтому в качестве поля не будет полноценным полем.
J>не переменная да согласен "не полноценное поле" это что такое ? )))
Ну, это у меня такая фигура речи. Я имел ввиду, что поменять значение такого поля — некоторая проблема.
В отличие от указателя — там обычное присваивание всегда работает.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Члены данных: что лучше ссылка или указатель?
Здравствуйте, okman, Вы писали:
O>Здравствуйте, Андрей Е, Вы писали:
АЕ>>В класс передается по ссылке или указателю некий объект(например файл), и затем ссылка или указатель сохраняется внутри, как член данных. И класс затем будет этот объект изменять(например записывать данные в файл). Объект передается в конструкторе, так что его можно передавать и хранить как по ссылке так и по указателю. В первом приближении вроде корректно работает и тот и тот вариант.
АЕ>>С одной стороны, вроде есть рекомендация, что если явно не нужны указатели, то следует использовать ссылки. АЕ>>С другой стороны, в книге "Стандарты программирования на C++" в совете 52, в самом конце утверждается, что наличие члена-ссылки почти наверняка является ошибкой.
АЕ>>Подскажите, пожалуйста, что предпочесть, ссылку или указатель?
O>Используя ссылки, можно достигнуть такого уровня контроля, который невозможен при указателях. O>Например, вы не сможете забыть проинициализировать ссылочный член класса, не присвоете ему O>ноль или недопустимое значение, не вызовете delete раньше времени. O>Не менее важно то, что объекты, которыми инициализируются ссылочные типы-члены, имеют явно O>определенное время жизни и должны быть сконструированы до инициализации включающего класса. O>Соответственно, они будут разрушаться в обратном порядке, то есть проблема "висячих ссылок" в O>большинстве случаев снимается.
O>Лично я стремлюсь использовать ссылки везде, где можно. O>Только когда это невозможно физически или явно нежелательно, возвращаюсь к указателям.
ну если указываемые объекты будут умирать после объектов содержащих ссылки или указатели на них то какая разница ссылка или указатель ? а если наоборот то никакой ссылкой не предотвратить преждевременной умирание указываемых объектов я это все к тому что это должен учитывать алгоритм а не ссылки vs указатели разве нет ?
Re[2]: Члены данных: что лучше ссылка или указатель?
Здравствуйте, art_kuz, Вы писали:
_>Если в процессе времени жизни класса данный член класса может меняться, _>но лучше использовать указатель\умный указатель.
"но" это "то", а "жизни класса" это "жизни объекта класса"? Тогда не лучше, а приходится.
Re[3]: Члены данных: что лучше ссылка или указатель?
Здравствуйте, igna, Вы писали:
I>Здравствуйте, art_kuz, Вы писали:
_>>Если в процессе времени жизни класса данный член класса может меняться, _>>но лучше использовать указатель\умный указатель.
I>"но" это "то", а "жизни класса" это "жизни объекта класса"? Тогда не лучше, а приходится.
Здравствуйте, Андрей Е, Вы писали:
АЕ>Подскажите, пожалуйста, что предпочесть, ссылку или указатель?
ссылка как поле класса — это абсолютный эквивалент константного указателя(не путать с указателем на константу)
тоесть:
type & === type * const
через стрелочку или точку доступ — не принципиально.
однако, возможно, имеетса в виду не константный указатель.
Тогда, очевидны различия:
получаем: возможность изменять(например, обнулить указатель после разрушения объекта).
теряем: обязательность инициализации в конструкторе.
Здравствуйте, Erop, Вы писали:
E>Умный указатель! Так как ситуация "несколько автоматических объектов ссылаются друг на друга" -- это очень частный случай взаимосвязанных объектов. E>Поэтому по умолчанию, связь объектов должна выражаться умными указателями. И только если есть какие-то веские причины к тому, то умные указатели можно заменить обычными. Почему тогда именно указателями, а не ссылками? Да потому, что умных ссылок в С++ не бывает (точку перегрузить нельзя)...
Умных ссылок не бывает, поэтому там где не применишь умный указатель нужно использовать не ссылку, а обычный указатель?
В следующем примере ссылку надо указателем заменить?:
Здравствуйте, igna, Вы писали:
I>В следующем примере ссылку надо указателем заменить?:
Тут это может быть немного неудобно, если внутри метода writer::write много пользуются операторами для вывода в поток.
Но если бы был указатель, то это точно было бы по крайней мере не хуже
I>
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Тут это может быть немного неудобно, если внутри метода writer::write много пользуются операторами для вывода в поток. E>Но если бы был указатель, то это точно было бы по крайней мере не хуже
Так "крайней мере не хуже" или все-таки "немного неудобно"?
Здравствуйте, Андрей Е, Вы писали:
АЕ>Подскажите, пожалуйста, что предпочесть, ссылку или указатель?
Когда-то ссылку, когда-то указатель, а когда-то умный указатель.
Одного рецепта на все случаи жизни нету.
В каждом конкретном случае можно дать совет и даже как-то его обосновать.
Здравствуйте, igna, Вы писали:
I>Так "крайней мере не хуже" или все-таки "немного неудобно"?
О чём именно речь? О хранении поля или о параметре конструктора?..
Если речь о поле, то делаешь приватный метод, который вернёт нужную ссылку + может и что-нибудь проверить ещё или ещё что-то сделать...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Если речь о поле, то делаешь приватный метод, который вернёт нужную ссылку + может и что-нибудь проверить ещё или ещё что-то сделать...
А где тут глубокий смысл использования указателя вместо ссылки?
Напомню, ты предложил по умолчанию использовать умные указатели, и только если есть веские причины, то указатели обычные. Ссылкам места вообще не оставил, вот я и привел пример со ссылкой, и спрашиваю, что мы выиграем, если заменим ссылку на указатель в следующем примере?:
Здравствуйте, Erop, Вы писали:
E>Что касается поля, то, например, мы выиграем возможность в любой момент перейти к shared_ptr, скажем, без изенений в остальном коде writer...
Согласен, это какой-никакой аргумент(ик). Для меня впрочем недостаточный.
PS. Тема обсуждения только про поле и есть, про параметр только ты и пишешь.
Здравствуйте, igna, Вы писали:
I>Согласен, это какой-никакой аргумент(ик). Для меня впрочем недостаточный.
Ну я могу ещё иначе сказать, часто бывает так, что если хочется написать член-ссыдку, то на самом деле стоит ещё что-то где-то подправить, чотбы не хотелось
I>PS. Тема обсуждения только про поле и есть, про параметр только ты и пишешь.
В класс передается по ссылке или указателю некий объект(например файл), и затем ссылка или указатель сохраняется внутри, как член данных. И класс затем будет этот объект изменять(например записывать данные в файл). Объект передается в конструкторе, так что его можно передавать и хранить как по ссылке так и по указателю. В первом приближении вроде корректно работает и тот и тот вариант.
IMHO, косяк тут начался уже там, где в конструктор объекта передают по ссылке то, указатель или ссылка на что будет сохранена в объекте.
Я всё-таки придерживаюсь теории, что при программировании мы про все ссылки должны предполагать, что они могут ссылаться на автоматический/временный объект. В частности сохранять в полях указатель на переданный по ссылке объект нехорошо.
Хот вот твой writer, например, как бы предполагает, что он сам должен быть автоматическим и его аргумент или статическим или автоматическим. Но это всё хорошо работает только до тех пор, пока ты не начнёшь как-то хитро своими писателями манипулировать (прихранивать там, или ещё что-то делать). Начнёшь манипулировать -- получишь нехилый шанс нарваться. Если не при разработке, то про поддержке кода...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Ну я могу ещё иначе сказать, часто бывает так, что если хочется написать член-ссыдку, то на самом деле стоит ещё что-то где-то подправить, чотбы не хотелось
Конкретный пример у тебя есть. Подправь.
E>Хот вот твой writer, например, как бы предполагает, что он сам должен быть автоматическим и его аргумент или статическим или автоматическим. Но это всё хорошо работает только до тех пор, пока ты не начнёшь как-то хитро своими писателями манипулировать (прихранивать там, или ещё что-то делать). Начнёшь манипулировать -- получишь нехилый шанс нарваться. Если не при разработке, то про поддержке кода...
Пока-что я понял, что можно нарваться используя ссылку в качестве параметра конструктора. Тем не менее на мой взгляд риск в данном случае оправдывается отсутствием необходимости проверки на 0. Но допустим, что параметр конструктора — указатель, что в этом случае говорит против использования ссылки в качестве поля? Где можно "нарваться"?
Здравствуйте, igna, Вы писали:
I>Конкретный пример у тебя есть. Подправь.
Я же сказал. Я бы передавал УКАЗАТЕЛЬ в конструктор и его же и хранил бы...
и сделал бы приватный или защищённый метод, скажем dst(), или output() который бы возвращал бы ссылку...
I>Где можно "нарваться"?
Ну, например, если тыбе захочется реализовать оператор присваивания писателя, или завести массив (std::vector) писателей...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Я же сказал. Я бы передавал УКАЗАТЕЛЬ в конструктор и его же и хранил бы... E>и сделал бы приватный или защищённый метод, скажем dst(), или output() который бы возвращал бы ссылку...
Ясно, спасибо. Думал может тебе код использующий writer подправить хочется, в смысле, само по себе наличие writer-а ты считаешь неправильным.
E>Ну, например, если тыбе захочется реализовать оператор присваивания писателя, или завести массив (std::vector) писателей...
Здравствуйте, igna, Вы писали:
I>Ясно, спасибо. Думал может тебе код использующий writer подправить хочется, в смысле, само по себе наличие writer-а ты считаешь неправильным.
Я не совсем понимаю что за код использует writer.
У тебя был пример этого класса, а не кода, который его использует.
I>Тогда я заменю ссылку на указатель.
И попадёшь на переписывание всего writer, как минимум...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском