LINUX.ORG.RU

java, возврат а-ля const значения

 


0

3

Итак, есть у меня класс, пусть будет Data, содержащий в себе одним из полей самопальное Tree<Object>. Иногда есть необходимость посмотреть снаружи ентое самое дерево целиком, при этом запретив изменение как его самого, так и его элементов. Поменять поле на final - не решение, ибо дерево таки меняется другими методами. Поскольку никаких возвратов const у нас языком не предусмотрено, я вижу только варианты:

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

- возвращать копию всего дерева - ну вы понели(с).

вопрос - есть ли все-таки способы сделать разумнее?

Ответ на: комментарий от wota

отдаем const Tree - и клиент не будет вызывать add_node

Клиент вообще ничего не сможет вызывать что не объявлено как const. О чем я и говорю - для того чтобы такое сработало - Tree должно быть сделано с соответствующим design convention - все иммутабельные методы должы быть объявлены конст - то есть продекларирован immutable интерфейс объекта. Тада! В жабе тоже самое - только там это делается через абстракцию интерфейса.

r ★★★★★
()
Ответ на: комментарий от r

Есть. И это не несет никаких проблем в С++. Ты передаешь ссылку на константный объект и никто не сможет вызывать мутирующий метод. Только константные.

anonymous
()
Ответ на: комментарий от wota

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

r ★★★★★
()
Ответ на: комментарий от r

Если это сложный объект Tree то у него будет метод а ля add_node - и торба.

Пусть будет. Его не сможет вызывать клиент(без хаков).

anonymous
()
Ответ на: комментарий от r

В C++ ее не может не быть. Понимаешь? Это в яве тебе нужно для этого писать специальный интерфейс и пр. В С++ тебе не надо делать ничего лишнего. Любой класс С++ отвечает за то, чтобы определить, что можно делать для константных объектов данного класса, а что нельзя. И компилятор в этом помогает, как может.

anonymous
()
Ответ на: комментарий от r

Уже приводили и ты на него даже отвечал.

anonymous
()
Ответ на: комментарий от r

все иммутабельные методы должы быть объявлены конст

В С++ по другому просто не бывает. Понимаешь?

anonymous
()
Ответ на: комментарий от r

с произвольным объектом (как метает топикстартер) такого не сделаешь

В С++ сделаешь. Т.к. в С++ все объекты придерживаются того, что ты называешь «иммутабельной спецификацией».

anonymous
()
Ответ на: комментарий от r

Tree должно быть сделано с соответствующим design convention - все иммутабельные методы должы быть объявлены конст

в нормальном коде на С++ по другому и не бывает

Тада! В жабе тоже самое - только там это делается через абстракцию интерфейса.

это совсем не тоже самое - вместо документирования кода ты плодишь лишние сущности и дублируешь код

wota ★★
()
Ответ на: комментарий от anonymous

В C++ ее не может не быть.

Серьезно?

struct Tree
{
    Tree(int _i):i(_i){}
    int i;
    int get_i() { return i;}
};

int main()
{
   const Tree t(10);
   t.get_i();
};

См магия воплщенная в реальность - немутирующйий метод не объявлен const - и сюрприз - его нельзя вызывать.

. В С++ тебе не надо делать ничего лишнего

В C++ тебе надо расставить const.

Любой класс С++ отвечает за то, чтобы определить,

Любой программист а не класс. И если программист не продекларировал const интерфейс - топикстартер в заднике. А если продекларировал - эквивалентная задача на жабе решается декларацией интерфейса как я описал выше.

r ★★★★★
()
Ответ на: комментарий от wota

в нормальном коде на С++ по другому и не бывает

ЧИТД - если класс задизайнен с учетом иммутабельности - то все телемаркет и там и там. Просто механизмы в жабе и плюсах для этого разные.

r ★★★★★
()
Ответ на: комментарий от wota

это совсем не тоже самое - вместо документирования кода ты плодишь лишние сущности и дублируешь код

Они совсем не лишние - у них много других функций. Просто «и эта тоже» решается интерфейсом.

r ★★★★★
()
Ответ на: комментарий от r

немутирующйий метод не объявлен const - и сюрприз - его нельзя вызывать.

Я вижу, что он объявлен мутирующим. Для этого достаточно посмотреть на интерфейс класса:

struct Tree
{
    Tree(int _i);
    int get_i();

    int i;
};

Для меня очевидно, что get_i меняет по мнению создателя класса состояние объекта, ведь он объявлен как мутирующий.

В C++ тебе надо расставить const.

Мне еще надо расставлять class, virtual, public, private и т.д. Я тебя не понимаю.

если программист не продекларировал const интерфейс

то он не найдет работу или будет уволен.

anonymous
()
Ответ на: комментарий от r

Просто механизмы в жабе и плюсах для этого разные.

В жабе нет для этого механизма. Есть некоторый паттерн(не зависимый от языка - я и в С++ могу так же сделать), который некоторые программисты применяют. В С++ это именно языковой механизм, который применяют ВСЕ. Не написать const для константного метода в С++ примерно тоже самое, что забыть поставить какой-нибудь virtual.

anonymous
()
Ответ на: комментарий от anonymous

Для меня очевидно, что get_i меняет по мнению создателя класса состояние объекта, ведь он объявлен как мутирующий.

А в жабе у топикс стартера сделано тоже самое.

Мне еще надо расставлять class, virtual, public, private и т.д. Я тебя не понимаю.

А в жабе надо сделать интерфейс. И там и там проблема решаема.

то он не найдет работу или будет уволен.

То есть язык здесь не при чем.

r ★★★★★
()
Ответ на: комментарий от r

А в жабе надо сделать интерфейс. И там и там проблема решаема.

А в С вместо virtual надо сделать таблицу указателей на функцию. И там и там проблема решаема.

То есть язык здесь не при чем

В ява не обязательно выделять «константные» методы в отдельный класс. И язык этому никак не способствует.

anonymous
()
Ответ на: комментарий от anonymous

В жабе нет для этого механизма.

Я там вверху привел механизм.

Есть некоторый паттерн(не зависимый от языка - я и в С++ могу так же сделать), который некоторые программисты применяют.

Который решает ту же самую проблему.

В С++ это именно языковой механизм, который применяют ВСЕ.

Который совсем не обязателен - следовательно это такой же паттерн. Вот если бы в плюсах была effect system которая константность вычисляла сама - можно было бы говорить что это делает язык. А так это делает человек. Язык ему помогает - он предоставил механизм const в плюсах и механизм interface в жабе. Но оба они зависят о прямоты рук.

r ★★★★★
()
Ответ на: комментарий от anonymous

В ява не обязательно выделять «константные» методы в отдельный класс. И язык этому никак не способствует.

В C++ тоже. Я привел программу - компиляется.

r ★★★★★
()
Ответ на: комментарий от r

В C++ тоже. Я привел программу - компиляется.

убери все private/protected/final из кода на Java - тоже вроде как ничего страшного не произошло, const из той же категории, просто у тебя его нет и делаешь вид, что он и не нужен, а значит и доказывать тебе что-либо нет смысла - ты настроен только отрицать

wota ★★
()
Последнее исправление: wota (всего исправлений: 1)
Ответ на: комментарий от r

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

anonymous
()
Ответ на: комментарий от anonymous

Невиртуальные функции тоже компиляются.

Невиртуальную функцию виртуально вызвать нельзя если надо - не скомпиляется. А если забить на константность вообще - все будет работать. А если хочешь вдруг запретить мутабельность - это волевое решение программера - надо писать в определенном паттерне. Тада! В жабе тоже работает такой подход - если нужна иммутабельность - пиши в определенном паттерне.

r ★★★★★
()
Ответ на: комментарий от wota

убери все private/protected/final из кода на Java - тоже вроде как ничего страшного не произошло, const из той же категории,

Именно. Я про это и говорю.

просто у тебя его нет и делаешь вид, что он и не нужен,

Я ничего такого не говорил - но в жабе он действительно практически не нужен. Там есть final + интерфейсы.

А вообще суть в том что вопрос как его ставит топикстартер не решился бы const методом класса Data. Он решился бы в плюсах const методом + определенным дизайном класса Tree. Тада - в жабе то же самое - если дизайн класса Tree подконтроле - у топикстартера проблем нет. Он просто в своем вопросе сделал ассиметричное допущение - что в жабе у него класс Tree кривой (см не соответствует возможности иммутабельности) а в плюсах он почему-то прямой - и потому там можно решить все const.

r ★★★★★
()
Ответ на: комментарий от r

Невиртуальную функцию виртуально вызвать нельзя если надо - не скомпиляется.

Че? Вызов никак не отличается.

А если забить на константность вообще - все будет работать.

Нет, не будет. И еще раз повторю - так НЕ делают. Покажи мне хоть один проект. Хотя бы на том же github'е.

А если хочешь вдруг запретить мутабельность - это волевое решение программера - надо писать в определенном паттерне.

Нет там никакого волевого решения. Это единственновозможная практика использования С++. А если как ты рассуждать, то о private можно тоже самое сказать.

Тада! В жабе тоже

Даже не мечтай. В жабе для этого нужно использовать паттерн-костыль. В С++ так тоже иногда делают, иногда бывают базовые классы лишь с константыми методами. Это не означает, что const не нужен.

anonymous
()
Ответ на: комментарий от r

Именно. Я про это и говорю.

Нет, ты говоришь о том, что const не решает проблему TC. А это тоже самое, что сказать, что private не решает проблему доступа к приватным полям.

Я ничего такого не говорил - но в жабе он действительно практически не нужен. Там есть final + интерфейсы.

Поверь мне, что подобных вопросов, что возникли у TC у С++ программиста даже не возникнет - он передаст ссылку/указатель на const Tree.

anonymous
()
Ответ на: комментарий от anonymous

Че? Вызов никак не отличается.

Ну работать будет неправильно. Один хрен.

Нет, не будет.

Что не будет работать?

И еще раз повторю - так НЕ делают.

Но язык не заставляет.

Это единственновозможная практика использования С++. А если как ты рассуждать, то о private можно тоже самое сказать.

А приват - это то же самое. И разные питонисты именно так и рассуждают.

В жабе для этого нужно использовать паттерн-костыль.

Это не паттерн костыль.

Это не означает, что const не нужен.

Это оозначает что проблема топикстартера не в языке - и там и там все решается прямо в рамках прямых рук.

r ★★★★★
()
Ответ на: комментарий от anonymous

Нет, ты говоришь о том, что const не решает проблему TC.

Нет - я говорю о том что топикстартер сделал ассиметричное утверждение относительно постановки задачи для двух разных языков - поставил ее по разному.

r ★★★★★
()
Ответ на: комментарий от r

Мля. Сколько классов в Java следуют такой модели? 0.0001%? А в С++ - 100%. Неужели не понятно? Язык так же следует этой модели, только он не телепат и может проверять только «физическую» константность. Но она не всегда совпадает с логической.

anonymous
()
Ответ на: комментарий от r

и там и там все решается прямо в рамках прямых рук.

Ну так покажи аналог того кода с shared_ptr'ами. Там Tree менять не пришлось.

anonymous
()
Ответ на: комментарий от r

немутирующйий метод не объявлен const - и сюрприз - его нельзя вызывать.

Взаимоисключающие параграфы. В языке С++ немутирующий метод == метод объявленный как const. Точно так же, как виртуальный метод == метод, объявленный virtual(или унаследованный), а закратый метод == метод, объявленный в разделе private. Так чего ты сказать-то хочешь? Что если не использовать ключевое слово, то оно не будет работать?

anonymous
()
Ответ на: комментарий от anonymous

В языке С++ немутирующий метод == метод объявленный как const.

А в джаве - немутируемый объект - объект не имеющий мутирующих методов в интерфейсе.

Что если не использовать ключевое слово, то оно не будет работать?

См про ассиметричную постановку задачи.

r ★★★★★
()
Ответ на: комментарий от r

А в джаве - немутируемый объект - объект не имеющий мутирующих методов в интерфейсе.

Нет. В яве нет понятия «мутирующий метод» на уровне контрактов. Т.е вообще. Наследник может его перекрыть и вызвать оттуда мутирующие методы, и вообще сделать все, что угодно, не получив даже предупреждения от компилятора.

Ты говоришь о некотором паттерне, реализуемом во многих языках, в том числе и в С++.

См про ассиметричную постановку задачи.

На что смотреть?

anonymous
()
Ответ на: комментарий от r

А в джаве - немутируемый объект - объект не имеющий мутирующих

методов в интерфейсе.

Можно ссылку на спецификацию Java по этому вопросу?

anonymous
()
Ответ на: комментарий от r

А в джаве - немутируемый объект - объект не имеющий мутирующих методов в интерфейсе.

Пруф или не было.

anonymous
()
Ответ на: комментарий от anonymous

Нет. В яве нет понятия «мутирующий метод» на уровне контрактов. Т.е вообще

А кто-то говорил что есть? Там иммутабельность делается не на уровне методов а на уровне переменных - final.


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

Не наследник а разработчик. Тот самый который не поставит конст.

На что смотреть?

На то что в C++ ожидается «правильный объект» - то есть со всеми расставленными констами - а в жабе почему-то кривая реализация - без иммутабельного интерфейса.

r ★★★★★
()
Ответ на: комментарий от r

А кто-то говорил что есть?

Ты:

А в джаве - немутируемый объект - объект не имеющий мутирующих методов в интерфейсе.

Не наследник а разработчик. Тот самый который не поставит конст.

Разработчик наследника не сможет в С++ не поставить const - это будет уже другой метод.

На то что в C++ ожидается «правильный объект» - то есть со всеми расставленными констами

Потому что в С++ по другому не бывает. const там для этого и существует. И его используют все. И без него твоя жизнь будет весьма уныла. Найди мне на гитхабе, в библиотеках или еще где-то неправильно заданную константность для С++.

а в жабе почему-то кривая реализация - без иммутабельного интерфейса.

Потому что в жабе большинство объектов такие.

anonymous
()
Ответ на: комментарий от r

Потому что в Java нет константности на уровне контрактов методов. В С++ же это часть контрактов. Т.е. если мы возьмем корректный объект в С++, то он будет «со всеми расставленными константами»(иначе он не будет корректным), но если мы возьмем корректный объект в Java, то он не будет обладать иммутабельным интерфейсом(или мы о нем тупо можем не знать, например, если код обобщенный).

anonymous
()
Ответ на: комментарий от r

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

Надо признать, что const одна из двух здравых идея Страуструпа(вторая - RAII, которые проник уже почти во все языки, в том или ином виде). Но const он с Ритчи обсуждал, так что наверняка не обошлось без его влияния. С кем он обсуждал RAII - не знаю, к сожалению.

forCe
()
Ответ на: комментарий от anonymous

Разработчик наследника не сможет в С++ не поставить const - это будет уже другой метод.

Я сказал не это. Я говорю о том что и там и там работает человек. В жабе почему-то человек может быть достаточны дебилом а в с++ не может потому что цитируя вас «никто так не делает»?

Потому что в С++ по другому не бывает.

Во - о чем я и говорю. В с++ разраб правильно расставляет консты - то есть следует грамоной практике с++. А в жабе он у вас почему-то хрониеский дебил.

Потому что в жабе большинство объектов такие.

Ничего подобного. Коллекции стандартной библиотеки не замучены на иммутабельность потому что такими сделаны специально. Хотя я на жабе не пишу уже года 4 - даже 4 года назад я поэтому не использовал стандартные коллекции.

r ★★★★★
()
Ответ на: комментарий от forCe

Ты не прав. const действительно нужен сам по себе.

Я где-то говорю что не нужен?

при чем меня теперь бесят либы, которые не думают о константности

Анонимусы говорят что их в природе не существует.

r ★★★★★
()
Ответ на: комментарий от r

Я где-то говорю что не нужен?

Да, ты говоришь, что в яве он не нужен. Хотя то, что ты предлагаешь в качестве решения на яве, можно сделать практически в любом языке. Короче, нет в яве аналога const и это плохо. Ты фактически предлагаешь два типа вместо одного, что сказывается, как уже говорилось, на обобщенном коде, например.

Анонимусы говорят что их в природе не существует.

Ну для крестов я их тоже не видел такого.

forCe
()
Ответ на: комментарий от r

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

anonymous
()
Ответ на: комментарий от forCe

Да, ты говоришь, что в яве он не нужен.

Нет - я говорю как проблемы топикстартера решаются в яве. Плакать о том что в яве нет const определенно бесполезно.

Ты фактически предлагаешь два типа вместо одного

Вообще-то я бы предложил то что в первом же коменте написал maxcom. Потому что как было тмечено ранее ни интерфейс ни const не гарантирет thread safety.

r ★★★★★
()
Ответ на: комментарий от anonymous

Ты сам же говоришь, что стандартные классы жабки не следуют этим правилам, но тут же утверждаешь, что это говнокод.

Нет - я говорю что стандартные классы жабки дизайнились с другой идеей. А не потому что там не осилели конст.

Кода на джаве, не использующего твой прием, хоть отбавляй.

Классы коллекций это тоже не рокет саянс. Это с++ STL создать - ипануться можно. А свой фреймворк коллекций на жабке как нефиг делать.

r ★★★★★
()

Поищите в интернете реализацию дерева, которое умеет read only O(1) snapshot. Такого много, в Scala в стандартной библиотеке вообще

vertexua ★★★★★
()
Ответ на: комментарий от r

А вот с какой бы целью/идеей не дизайнились классы(не только стандартные) С++, корректность константности там будет соблюдена ;) Я С++ терпеть не могу(предпочитаю сишечку), но в плане cost они явно в плюсе.

forCe
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.