| OberonCore https://forum.oberoncore.ru/ |
|
| ГудвинЪ. Великий и ужасТный! https://forum.oberoncore.ru/viewtopic.php?f=26&t=1381 |
Страница 1 из 2 |
| Автор: | Wlad [ Четверг, 05 Март, 2009 12:47 ] |
| Заголовок сообщения: | ГудвинЪ. Великий и ужасТный! |
Набрёл в Сети вот на это: http://habrahabr.ru/blogs/cpp/53576/ Опять вспомнилось, взгрустнулось, пожалелось о массах заблудшихЪ... |
|
| Автор: | Alexey Veselovsky [ Четверг, 05 Март, 2009 15:40 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Владимир Лось писал(а): Набрёл в Сети вот на это: http://habrahabr.ru/blogs/cpp/53576/ Опять вспомнилось, взгрустнулось, пожалелось о массах заблудшихЪ... А что собственно не так? Ты пользователь класса A, видишь только его спецификацию. Было бы странно предположить что в функцию вдруг передастся что-то отличное от 10. Если пользователю не нравится дефолтная десятка, то он волен задать своё значение. Ни о каких двадцатках он не знает и знать не может. Также он не знает метод какого конкретного класса вызовется, ибо не его это дело. Полиморфизмъ. Если бы функция вызвалась бы с параметром 20, то это было бы нарушением контракта. |
|
| Автор: | Wlad [ Четверг, 05 Март, 2009 15:51 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Alexey Veselovsky писал(а): Владимир Лось писал(а): Набрёл в Сети вот на это: http://habrahabr.ru/blogs/cpp/53576/ Опять вспомнилось, взгрустнулось, пожалелось о массах заблудшихЪ... А что собственно не так? Ты пользователь класса A, видишь только его спецификацию. Было бы странно предположить что в функцию вдруг передастся что-то отличное от 10. Если пользователю не нравится дефолтная десятка, то он волен задать своё значение. Ни о каких двадцатках он не знает и знать не может. Также он не знает метод какого конкретного класса вызовется, ибо не его это дело. Полиморфизмъ. Если бы функция вызвалась бы с параметром 20, то это было бы нарушением контракта. А если я - ПОЛЬЗОВАТЕЛЬ КЛАССА В??? Как? Практически ВСЕ, кого спросил (кроме двух), указали 20. Один сказал 10, потому, что новичок и неправильно понимал поведение и правила перекрытия виртуальных функций в Си++, второй - до этого прочитал статью. Все остальные (даже сторонники и приверженцы Си++), заметили "разветвлённость" понятийного момента (по правилам виртуализации и по умолчаниям в аргументах). Все хором сошлись на "хорошо в пятнадцати строчках! А попробуй найти лопух в десятках тысячах строк проекта, ежели чаво!..." Наше - вам! ЗЫ Кроме того, уж извините, но при таком раскладе, как в примере, я НИКАК не могу быть "пользователем класса А"... Подумайте - почему? |
|
| Автор: | Alexey Veselovsky [ Четверг, 05 Март, 2009 16:07 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Цитата: Кроме того, уж извините, но при таком раскладе, как в примере, я НИКАК не могу быть "пользователем класса А"... Подумайте - почему? Потому, что сами создали экземпляр B? |
|
| Автор: | Alexey Veselovsky [ Четверг, 05 Март, 2009 16:09 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Цитата: А если я - ПОЛЬЗОВАТЕЛЬ КЛАССА В??? Как? А если вы пользователь класса B, то будет 20. Что не так? |
|
| Автор: | Geniepro [ Четверг, 05 Март, 2009 16:11 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Да, как хорошо, что в том быдлокоде, которым я сейчас отягощён, нет таких наворотов -- ни виртуальных функций, ни перегрузки операторов, ни аргументов по умолчанию, ни шаблонов! А то я бы повесился! |
|
| Автор: | Vlad [ Четверг, 05 Март, 2009 19:08 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Владимир Лось писал(а): Набрёл в Сети вот на это: http://habrahabr.ru/blogs/cpp/53576/ Опять вспомнилось, взгрустнулось, пожалелось о массах заблудшихЪ... Лично у меня никаких проблем с этим примером не возникло. Достаточно представлять (в общих чертах) как реализуются виртуальные функции в C++ и хотя бы раз попытаться сделать указатель на функцию с дефолтовым аргументом. P.S. Хотя конечно я бы предпочел, чтобы компилятор ругался в таких случаях (у него для этого все есть). |
|
| Автор: | Wlad [ Четверг, 05 Март, 2009 23:36 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Alexey Veselovsky писал(а): Цитата: А если я - ПОЛЬЗОВАТЕЛЬ КЛАССА В??? Как? А если вы пользователь класса B, то будет 20. Что не так? Это Вы имеете, конечно в виду, что у меня переменная указатель будет типа указателя на класс В? ЕЩЁ СМЕШНЕЕ, ЕЙ БОГУ! |
|
| Автор: | Alexey Veselovsky [ Пятница, 06 Март, 2009 00:25 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Владимир Лось писал(а): Alexey Veselovsky писал(а): Цитата: А если я - ПОЛЬЗОВАТЕЛЬ КЛАССА В??? Как? А если вы пользователь класса B, то будет 20. Что не так? Это Вы имеете, конечно в виду, что у меня переменная указатель будет типа указателя на класс В? ЕЩЁ СМЕШНЕЕ, ЕЙ БОГУ! Я безусловно рад что вам весело, однако не поделитесь ли поводом столь бурного веселья? Хотелось бы тоже порадоваться. |
|
| Автор: | Wlad [ Пятница, 06 Март, 2009 01:00 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Alexey Veselovsky писал(а): Я безусловно рад что вам весело, однако не поделитесь ли поводом столь бурного веселья? Хотелось бы тоже порадоваться. Будете также радоваться, когда уясните роль языка, как средства поддержки/"противодействия" проектных(ым) решений(ям). Моё веселье - от осознания (даже на таком маленьком примере!) убожества Си++ именно с точки зрения на него, как на средство проектирования, а не как на инструмент для хитровы..., пардон, изощрённых кодовых примеров, позволяющих показать изворотливость и остроту умища отдельных индивидов. Данный пример совершенно далёк от какой-то реальной работы и проекта. Тем более высока его ценность. Объясняю. А Вы постарайтесь проникнуться. В данном примере я объявляю указатель на А, НО присваиваю ему экземпляр В. То есть само это действие АБСОЛЮТНО ОСМЫСЛЕНО. Причина объявления именно указателя на А может быть только одна (но она не отражена в примере) - где-то есть нечто, что принимает на входе именно указатели на А, как сущности для каких-то обобщённых, абстрактных, довольно высокоуровневых алгоритмов, ничего про детализацию в наследниках или не знающих, или не желающих знать. НО!, Прошу ещё раз вспомнить, что инициализирую-то я мой указатель ссылкой на экземпляр типа В!. И делаю это я (в примере, как части чего-то большего, очевидно!) СОВЕРШЕННО СОЗНАТЕЛЬНО! Но сам смысл введения наследника от А в виде В подразумевает существования чего-то такого, что или уточняется или отличается в наследниках от того же в предках. В данном примере (одним из?) таких видимых явных отличий как раз и является "значение по умолчанию". И, по логике оно там абсолютно правильно стоит. Конечно, можно было бы его неким образом через "задержанную инициализацию в конструкторе наследника" провести, но мы знаем классный механизм и способ - "значение аргумента метода по умолчанию". Кроме того, нам известен общий принцип переопределения и перекрытия виртуальных методов. А ну-ка, объединим наши проектные решения с возможностями языка! Опппа - облом-с! Оказывается, в случае работы с виртуалами, работает нечто, что поддерживает нашу логику (и работает правильно! "по логике" ИСХОДЯ ИЗ ДИНАМИЧЕСКОГО ТЕКУЩЕГО ТИПА ЭКЗЕМПЛЯРА),а вот другая особенность языка, почему-то "оглядывается" на СТАТИЧЕСКИЙ ТИП! И желаемое проектное решение сливается в унитаз... Вот поэтому мне - да - смешно! Я этим убожищем, слава Б-гу! не пользуюсь. |
|
| Автор: | Alexey Veselovsky [ Пятница, 06 Март, 2009 01:15 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Владимир Лось писал(а): Данный пример совершенно далёк от какой-то реальной работы и проекта. Тем более высока его ценность. Объясняю. А Вы постарайтесь проникнуться. В данном примере я объявляю указатель на А, НО присваиваю ему экземпляр В. То есть само это действие АБСОЛЮТНО ОСМЫСЛЕНО. Причина объявления именно указателя на А может быть только одна (но она не отражена в примере) - где-то есть нечто, что принимает на входе именно указатели на А, как сущности для каких-то обобщённых, абстрактных, довольно высокоуровневых алгоритмов, ничего про детализацию в наследниках или не знающих, или не желающих знать. Это действие (приведеённое в примере) абсолютно бессмысленно. Код: void foo(A* p_a) {// что-то тут делаем с А} int main() { B* p_b = new B; foo(p_b); } Нет ни малейшего смысла в указателе p_b типа A*. |
|
| Автор: | Wlad [ Пятница, 06 Март, 2009 01:48 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Vlad писал(а): Лично у меня никаких проблем с этим примером не возникло. Достаточно представлять (в общих чертах) как реализуются виртуальные функции в C++ и хотя бы раз попытаться сделать указатель на функцию с дефолтовым аргументом. Ой-ли?Или это так по мозгам трактором логики Си++ проезжаются? Vlad, с логикой переназначения виртуальных функций все знакомы. Идя от общего к частному, и считая, что таки описание функции-члена принадлежит конкретному классу, почему вдруг, оказывается, что функция назначается динамикой (по таблице виртуальных методов), а назначение значений по умолчанию в аргументах - по статике? Vlad писал(а): P.S. Хотя конечно я бы предпочел, чтобы компилятор ругался в таких случаях (у него для этого все есть). То есть, у вас тоже "червь сомнения есть" и Вы хотели бы тоже не упустить из памяти возможность такого рода "зевка"? Кроме того вот это (повторю исчо раз) сильно порадовало: Vlad писал(а): и хотя бы раз попытаться сделать указатель на функцию с дефолтовым аргументом То есть мало того, что бы удивиться исковерканной логике, надо ещё и закрепить наглядным примером и сверху "камешком придавить" просмотром результата в отладчике! С закреплением на подкорке! Вот только программер,почему-то, всё же от компилятора напоминания в виде ворнинга-таки возжелал... |
|
| Автор: | Wlad [ Пятница, 06 Март, 2009 01:51 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Alexey Veselovsky писал(а): Код: void foo(A* p_a) {// что-то тут делаем с А} int main() { B* p_b = new B; foo(p_b); } Нет ни малейшего смысла в указателе p_b типа A*. А если так foo(new B); ? |
|
| Автор: | Alexey Veselovsky [ Пятница, 06 Март, 2009 02:49 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Владимир Лось писал(а): Цитата: Нет ни малейшего смысла в указателе p_b типа A*. А если так foo(new B); ? Можно и так. Но если использовать после вызова foo объект таки как-то хочется (например уничтожить его), то указатель можно и сохранит. Кстати, проверил, в Аде в точности то же самое с параметрами по умолчанию. Код: package X is type A is tagged null record; procedure foo ( Self : in A; num : Integer := 0); type B is new A with null record; procedure foo (Self: in B; num : Integer := 10); procedure test (some : A'class); end X; Код: with Ada.Text_IO; use Ada.Text_IO; package body X is procedure foo ( Self : in A; num : Integer := 0) is begin Put_Line("A::foo"); Put_Line(Integer'Image(num)); end foo; procedure foo (Self: in B; num : Integer := 10) is begin Put_Line("B::foo"); Put_Line(Integer'Image(num)); end foo; procedure test (some : A'class) is begin foo(some); end test; begin null; end X; Код: with X; procedure Main is B : X.B; A : X.A; begin X.test(B); X.test(A); null; end; вывод программы писал(а): /home/valexey/main
B::foo 0 A::foo 0 |
|
| Автор: | Vlad [ Пятница, 06 Март, 2009 07:49 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Владимир Лось писал(а): Но сам смысл введения наследника от А в виде В подразумевает существования чего-то такого, что или уточняется или отличается в наследниках от того же в предках. Ваши размышления вполне понятны. Но я уверен, что вы поймете и такое размышление. Пользователь класса A, вызывая его метод с дефолтовым параметром, может быть уверен, что в качестве параметра подставится именно то, что он видит в объявлении класса А, а не что-то перекрытое в его наследнике только потому, что функция оказалась виртуальной. А если нужна виртуальность дефолтового параметра, то это делается явно - заводится еще одна виртуальная функция. Лично мне оба этих размышления кажутся равноценными по осмысленности. |
|
| Автор: | Wlad [ Пятница, 06 Март, 2009 10:27 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Vlad писал(а): Ваши размышления вполне понятны. Но я уверен, что вы поймете и такое размышление. Пользователь класса A, вызывая его метод с дефолтовым параметром, может быть уверен, что в качестве параметра подставится именно то, что он видит в объявлении класса А, а не что-то перекрытое в его наследнике только потому, что функция оказалась виртуальной. А если нужна виртуальность дефолтового параметра, то это делается явно - заводится еще одна виртуальная функция. Лично мне оба этих размышления кажутся равноценными по осмысленности. Понимаю. Но принять - решительно отказываюсь.А если я - пользователь класса В и ожидаю, что, не смотря на обобщённый указатель (например в коллекции) у меня наследники будут иметь правильно инициализированные поля класса (которые через параметры по умолчанию получили свои значения)? Вы советуете "завести ещё одну виртуальную функцию?" ОК, посмотрим и на это. Во-первых, я могу не иметь доступа к исходникам класса А. Точка. Во-вторых, для "пользователя класса А", буде появляется параметр по умолчанию, УЖЕ ПРОСТО ПО СМЫСЛУ ВСЁ РАВНО, КАК БУДЕТ ПРОИНИЦИАЛИЗИРОВАН ЭКЗЕМПЛЯР А (ИЛИ ЕГО НАСЛЕДНИК). Собственно для того мы параметр по умолчанию и втулили. А вот пользователю класса В - уже - НЕТ, НЕ ВСЁ РАВНО. Теперь уже смысл факта переопределения умолчания как раз в том, что экземпляры В чем-то и отличаются от экземпляров А (там одно умолчание, здесь - другое - всё ОК - "так задумано")... И - что? Получается, здесь язык ставит препоны для реализации нашего решения о различии? "Пользователи класса А" так и будут работать в терминах и понятиях уровня класса А (более обощённые алгоритмы). А конкретика поведения и наполнения - в наследниках. Но тут мы получили противоречие, исходящее из конкретного свойства языка. Пока, что Ваши доводы меня не убеждают. Может быть Вы, как более плотно работающий с этим, извиняюсь за выражение, языком программирования, укажете (по-конкретнее) на рассуждения автора языка или комитетчиков по поводу обоснования такого поведения? |
|
| Автор: | Wlad [ Пятница, 06 Март, 2009 10:31 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Alexey Veselovsky писал(а): Кстати, проверил, в Аде в точности то же самое с параметрами по умолчанию. Не на гнате, случаем, проверяли?... Ничего противоречивого из того, что там действительно объявлено, с тем, что вызывается и показывается, я лично, не вижу. Что инициализировалось, то и показалось (по типам объявлений и ожидаемым от этого вызовов)... |
|
| Автор: | Alexey Veselovsky [ Пятница, 06 Март, 2009 10:35 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Владимир Лось писал(а): Alexey Veselovsky писал(а): Кстати, проверил, в Аде в точности то же самое с параметрами по умолчанию. Не на гнате, случаем, проверяли?... На гнате. Гнат полностью соответствует стандарту Ада-95, т.о. это не имеет значения. |
|
| Автор: | Vlad [ Пятница, 06 Март, 2009 16:18 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Владимир Лось писал(а): Или это так по мозгам трактором логики Си++ проезжаются? Можете называть это "трактором", но "чувствовать" используемый язык - это вполне естественно. Этот пример - хороший вопрос для собеседования, возьму на вооружение. Хороший - не потому что хитрый или с подвохом, а потому что как раз на "чувствование" и потому что есть о чем поговорить независимо от правильности ответа. Владимир Лось писал(а): Vlad, с логикой переназначения виртуальных функций все знакомы. Идя от общего к частному, и считая, что таки описание функции-члена принадлежит конкретному классу, почему вдруг, оказывается, что функция назначается динамикой (по таблице виртуальных методов), а назначение значений по умолчанию в аргументах - по статике? Ну хотя бы потому, что аргументы в C++ всегда статичны и никак не влияют на виртуальность (нет в C++ виртуальности по типу аргумента, например). Единственное исключение тут можно усмотреть в ковариантных виртуальных функциях, и то оно относится к возвращаемому типу, а не к аргументам. Владимир Лось писал(а): Vlad писал(а): P.S. Хотя конечно я бы предпочел, чтобы компилятор ругался в таких случаях (у него для этого все есть). То есть, у вас тоже "червь сомнения есть"У меня нет сомнений в правильности такого дизайна или его какой-то ущербности (на что вы тут делаете упор). Предлагаемый вами дизайн ничуть не лучше (легко представить что и при таком дизайне кто-то мог сильно ругаться). Просто раз ситуация допускает разное толкование, то ее надо избежать. Тем более что это уже сделали для forward declaration обычных функций и шаблонов классов. Владимир Лось писал(а): Vlad писал(а): и хотя бы раз попытаться сделать указатель на функцию с дефолтовым аргументом То есть мало того, что бы удивиться исковерканной логике, надо ещё и закрепить наглядным примером и сверху "камешком придавить" просмотром результата в отладчике! С закреплением на подкорке! Вот только программер,почему-то, всё же от компилятора напоминания в виде ворнинга-таки возжелал... Отладчик здесь вообще никаким боком. Достаточно понимания, что дефолтовый аргумент никак не влияет на тип указателя на функцию (и никак не участвует при создании экземпляра такого указателя). Если программист на C++ этого не понимает, то у него большой пробел в понимании языка. P.S. Если у вас есть такое сильное желание поглумиться над ущербным дизайном C++ на примере дефолтовых аргументов, то это намного проще сделать без всяких виртуальных функций. file1.cpp: void f(int i) { std::cout << i << std::endl; } file2.cpp: void f(int i = 10); void test1(){ f(); } file3.cpp void f(int i = 20); void test1(); void test2(){ f(); } int main() { test1() test2(); } Здесь даже нарушения ODR нет, если я правильно понимаю. А вот проблема с дизайном языка - налицо. |
|
| Автор: | Vlad [ Пятница, 06 Март, 2009 17:24 ] |
| Заголовок сообщения: | Re: ГудвинЪ. Великий и ужасТный! |
Владимир Лось писал(а): А если я - пользователь класса В и ожидаю, что, не смотря на обобщённый указатель (например в коллекции) у меня наследники будут иметь правильно инициализированные поля класса (которые через параметры по умолчанию получили свои значения)? Для инициализации полей класса в C++ принято использовать конструкторы. А вообще в ООП - фабрики. И в конструкторах и в фабриках вы можете использовать параметры по умолчанию Владимир Лось писал(а): Вы советуете "завести ещё одну виртуальную функцию?" ОК, посмотрим и на это. Во-первых, я могу не иметь доступа к исходникам класса А. Точка. Значит дизайнер класса A не предполагал, что "дефолтовость" будет перегружаться. Мало того, пользователь класса A на такое тоже не расчитывает. Вообще в классе A можно много чего сделать не так и исходников не будет. Например сама функция могла быть невиртуальной. Так что ж теперь, требовать от языка возможности переделать все налету? Ну есть такие языки, у них есть свои проблемы Владимир Лось писал(а): Во-вторых, для "пользователя класса А", буде появляется параметр по умолчанию, УЖЕ ПРОСТО ПО СМЫСЛУ ВСЁ РАВНО, КАК БУДЕТ ПРОИНИЦИАЛИЗИРОВАН ЭКЗЕМПЛЯР А (ИЛИ ЕГО НАСЛЕДНИК). Собственно для того мы параметр по умолчанию и втулили. А вот пользователю класса В - уже - НЕТ, НЕ ВСЁ РАВНО. Теперь уже смысл факта переопределения умолчания как раз в том, что экземпляры В чем-то и отличаются от экземпляров А (там одно умолчание, здесь - другое - всё ОК - "так задумано")... И - что? Получается, здесь язык ставит препоны для реализации нашего решения о различии? В языке есть базовый механизм переопредения поведения - виртуальные функции. Вы хотите в добавок к этому механизму иметь виртуальность дефолтовых аргументов. Но такого механизма не сделали и по ряду причин. При этом оставили грабли в виде возможности переопределять дефолтовое значение в наследниках. Что вас не устраивает? Грабли сами по себе? Да, меня тоже они не устраивают. Невиртуальность дефолтовых аргументов? Так это легко достигается все через тот же базовый механизм. Владимир Лось писал(а): Пока, что Ваши доводы меня не убеждают. Может быть Вы, как более плотно работающий с этим, извиняюсь за выражение, языком программирования, укажете (по-конкретнее) на рассуждения автора языка или комитетчиков по поводу обоснования такого поведения? Покажите мне язык, где имеется желаемое вами поведение для дефолтовых аргументов (со статической типизацией, естественно). |
|
| Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
| Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |
|