Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.156] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 204 205 [206] 207 208 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#3076
,
|
|
|
|
Ну, если ты не имел в виду, что абсолютно нет никакого практического смысла в изменении значений переменным, а создание копий следует делать только тому, кому это вдруг в редком случае понадобится, и делать это он должен самостоятельно, как ему показалось удобным, то да, я ничего не понял. Впрочем, тебя вообще никто не понял из тех, кто отписался тебе в ответ.
|
|
Сообщ.
#3077
,
|
|
|
|
Цитата Qraizer @ Ну, если ты не имел в виду, что абсолютно нет никакого практического смысла в изменении значений переменным, а создание копий следует делать только тому, кому это вдруг в редком случае понадобится, и делать это он должен самостоятельно, как ему показалось удобным, то да, я ничего не понял. Впрочем, тебя вообще никто не понял из тех, кто отписался тебе в ответ. нет, я лишь имел ввиду, что делать оператор присваивания методом -- плохая затея |
|
Сообщ.
#3078
,
|
|
|
|
Ничего ты не понял. Цитата Повстанець @ Ссылочные типы ввели из-за того, что по другому не возможно реализовать сборщик мусора. Объектные типы оставили, чтобы разгрузить сборщик мусора и добавить быстродействие. В делфи, как всегда, фичу ввели, но наполовину. Ссылочные типы есть. Сборщика мусора нет. Начнём с того, что в основе методологии ООП лежит понятие "объект", целями "объекта" являются отражение абстрактной модели некой проблемы и наличие средств её решения, что вытекает в такие свойства "объекта", как "состояние" и "поведение" и как правило они напрямую взаимосвязанные, а наличие нескольких однотипных "объектов", со своими индивидуальными "состояниями", определяет ещё одно свойство - "уникальность", получается, что каждый отдельно взятый "объект", несмотря на наличие одного и того же интерфейса "средств решения проблемы" из общего числа однотипных ему "объектов", нацелен на решение конкретной проблемы, т.е. "объекты" могут использоваться совершенно разными способами и иметь своё индивидуальное "состояние" и соответственно "поведение" и так как "объекты" сами по себе, отдельно взятые, находятся в состоянии покоя, для их функционирования и получения результата необходимо внешнее воздействие других "объектов", это осуществляется путём передачи "объектов" через цепочку других "объектов" - субъектов, воздействующие на "состояние" "объектов", очень важный момент - это сохранение и передача изменённого "состояния" "объекта" на протяжении всех этапов цепочки, с возможным возвратом изменённого в итоге "состоянием", в конкретно взятом ОО ЯП это достигается путём передачи "объекта" не по "значению" а по указателю на место хранения "значения" "объекта" (переменной-ссылки), такой важный момент по определению ООП обязан быть прозрачным, это приоритетнее прозрачности копирования (и хранения) по значению, иначе, как заметил Romkin, это больше походит на структурное программирование. Это было "Раз". Второе: "динамичность объектов", тут разжёвывать не надо - это динамическое управление существованием некоторого множества "объектов", взаимодействующих друг с другом, статичными объектами этого не добится. Третье, неразрывно связано со вторым: "полиморфизм" Цитата Положение теории типов, согласно которому имена (например, переменных) могут обозначать объекты разных (но имеющих общего родителя) классов. Следовательно, любой объект, обозначаемый полиморфным именем, может по своему реагировать на некий общий набор операций. А кто там говорил про "большие возможности - большая ответственность" а? Цитата KILLER @ Та ладно Вернемся к виртуальным конструкторам? Что будет если вызвался конструктор производного класса раньше чем конструктор базового инициализировал свой член, который конструктор производного, так тщетно пытается заюзать? ССЗБ будет, не нет необходимости - не вызывай. Цитата KILLER @ А что будет если мы теперь удалим базовый класс, а производный все еще будет жить и использовать члены/методы базового? В Delphi такое физически не возможно, отдельно базовый класс из производного ты ну ни коем образом не вычленишь и не удалишь, а то о чём ты говоришь - это вызовы деструкторов, гле написан твой код деинициализации полей. И вообще эту тему уже не раз перетирали. Цитата D_KEY @ Язык позволяет это по той простой причине, что правила для пользовательских типов не должны отличаться от правил для встроенных. В противном случае получаем кривую систему типов, где куда не плюнь - свои правила. Во первых: правила не отличаются, точнее их всего два: значимый тип и ссылочный тип (а отсутствие одного из них - не представляется возможным). Во вторых: тогда уж "кривая система типов" в языке - это не "куда не плюнь - свои правила", а ограниченный ассортимент встроенных типов, влекущих за собой "собираем из того, что есть" и "осторожно! торчат гвозди" (здесь я про C++ и тип std::string в частности). А если по tapl, то система типов - это гибко управляемый синтаксический метод доказательства отсутствия определённых видов поведения при помощи классификации выражений языка по разновидностям вычисляемых или значений (вот декларирование переменной std::string включает в себя нюансы "определённых видов поведения"?). Цитата D_KEY @ Согласен. В чистом С++ это есть на уровне шаблонов и только на время компиляции. В рантайм это не вынести, поскольку противоречит принципу "что не использую, за то не плачу". ... Согласен. Но не допустимо на уровне чистого С++, ибо также противоречит вышеуказанному принципу и ограничивает сферы применения языка. Вот на почве такого "жлобства" (в случаях когда оно не оправданно) у программистов С++ определённо выработалось "статическое мышление", а как же работа с динамическими объектами? А ведь это же одна из тех вещей, ради которой и создавалось ООП и не использование которой, так яростно критикуется противниками этой парадигмы. Вот уж реализации шаблонов и макросов на уровне среды разработки - точно не приводят к потерям в конечном результате. |
|
Сообщ.
#3079
,
|
|
|
|
Цитата DesweR @ ССЗБ будет, не нет необходимости - не вызывай. Да ну? А я вот запутался, мне нужна была эта фича, я ее юзнул и забыл про член, который в базовом классе, еще не инициализировался до его уже использования... Цитата DesweR @ В Delphi такое физически не возможно, отдельно базовый класс из производного ты ну ни коем образом не вычленишь и не удалишь, а то о чём ты говоришь - это вызовы деструкторов, гле написан твой код деинициализации полей. И вообще эту тему уже не раз перетирали. Тогда давай уж называть все своими именами, ты хотел сказать деинициализатор ведь, а не деструктор? Деструктор на сколько я знаю, разрушает объект и освобождает ресурсы, которые он занимал... А теперь внимание вопрос, зачем мне тогда писать деинициализацию объектов класса? Яж так понимаю, память ты там тоже освобождать будешь? Если да, то какая же это деинициализация, это уже как раз таки разрушение, и если объект у тебя удалица, а потом в потомке у тебя будет использоваться - это уже ты выхватишь AV! |
|
Сообщ.
#3080
,
|
|
|
|
Цитата KILLER @ Да ну? А я вот запутался, мне нужна была эта фича, я ее юзнул и забыл про член, который в базовом классе, еще не инициализировался до его уже использования... Да тут не забыть, тут ослепнуть надо Цитата KILLER @ Тогда давай уж называть все своими именами, ты хотел сказать деинициализатор ведь, а не деструктор? Деструктор на сколько я знаю, разрушает объект и освобождает ресурсы, которые он занимал... А теперь внимание вопрос, зачем мне тогда писать деинициализацию объектов класса? Яж так понимаю, память ты там тоже освобождать будешь? Если да, то какая же это деинициализация, это уже как раз таки разрушение, и если объект у тебя удалица, а потом в потомке у тебя будет использоваться - это уже ты выхватишь AV Чего сказать то хотел? |
|
Сообщ.
#3081
,
|
|
|
|
Цитата KILLER @ А теперь внимание вопрос, зачем мне тогда писать деинициализацию объектов класса? Яж так понимаю, память ты там тоже освобождать будешь? Если да, то какая же это деинициализация, это уже как раз таки разрушение, и если объект у тебя удалица, а потом в потомке у тебя будет использоваться - это уже ты выхватишь AV! Брр. Тебе уже объясняли, что в Delphi объект единая сущность, он не делится на предков/потомков и тому подобное. Поэтому деструктор тоже один. Конструктор - тоже. В отличие от С++, в котором объект это целая шведская семья |
|
Сообщ.
#3082
,
|
|
|
|
Цитата DesweR @ Да тут не забыть, тут ослепнуть надо Как раз таки, вот такие случаи - очень часто ведут к ошибкам, причем не компиляции, тут не нужно ослепнуть, тут всеголишь нужно забыть, что ты за каким то фигом завел в базовом классе член, который используется производным(что в принципе и правильно), но работашь ты с этим объектом в производном классе, до того как его поринициализировал базовый Цитата DesweR @ Чего сказать то хотел? Хотел сказать, что ты был абсолютно не прав, говоря что: Цитата DesweR @ В Delphi такое физически не возможно, отдельно базовый класс из производного ты ну ни коем образом не вычленишь и не удалишь, а то о чём ты говоришь - это вызовы деструкторов, гле написан твой код деинициализации полей. Потому как АV тыв выхватишь, если не то не там напишешь Цитата Romkin @ Брр. Тебе уже объясняли, что в Delphi объект единая сущность, он не делится на предков/потомков и тому подобное. Поэтому деструктор тоже один. Конструктор - тоже. В отличие от С++, в котором объект это целая шведская семья Почему, вы(я имею ввиду делфистов) противоречите частенько сами себе? Я ключевые моменты, выделил жирным в твоих цитатах, и они противоречат друг другу... Если чо, в С++ не шведская семья, это называется иерархия наследования! Что позволяет избежать кучу ошибок, которые делаете в частности вы в делфи, а еще позволяет львиную долю создания/удаления объекта перенести на машину, а не на человека - как это сделано у вас, что еще более сокращает количество ошибок, и код становится более устойчивым к исключительным ситуациям А вот это в частности, то, что писал ты позавчера и которое противоречит тому, что ты говоришь сейчас: Цитата Цитата Romkin @ Исторически у программиста Delphi есть власть полностью отрубить потомка от предка. Вообще, потомок - самостоятельная сущность, которая просто может использовать код и данные предка. А может и не использовать... |
|
Сообщ.
#3083
,
|
|
|
|
KILLER, во второй цитате речь идет про унаследованную функциональность.
Цитата KILLER @ а еще позволяет львиную долю создания/удаления объекта перенести на машину, а не на человека - как это сделано у вас, что еще более сокращает количество ошибок, и код становится более устойчивым к исключительным ситуациям Ну-ну. Вот тебе код конструктора: ![]() ![]() function _ClassCreate(AClass: TClass; Alloc: Boolean): TObject; asm { -> EAX = pointer to VMT } { <- EAX = pointer to instance } PUSH EDX PUSH ECX PUSH EBX TEST DL,DL JL @@noAlloc CALL DWORD PTR [EAX] + VMTOFFSET TObject.NewInstance @@noAlloc: {$IFNDEF PC_MAPPED_EXCEPTIONS} XOR EDX,EDX LEA ECX,[ESP+16] MOV EBX,FS:[EDX] MOV [ECX].TExcFrame.next,EBX MOV [ECX].TExcFrame.hEBP,EBP MOV [ECX].TExcFrame.desc,offset @desc MOV [ECX].TexcFrame.ConstructedObject,EAX { trick: remember copy to instance } MOV FS:[EDX],ECX {$ENDIF PC_MAPPED_EXCEPTIONS} POP EBX POP ECX POP EDX RET {$IFNDEF PC_MAPPED_EXCEPTIONS} @desc: JMP _HandleAnyException { destroy the object } MOV EAX,[ESP+8+9*4] MOV EAX,[EAX].TExcFrame.ConstructedObject TEST EAX,EAX JE @@skip MOV ECX,[EAX] MOV DL,$81 PUSH EAX CALL DWORD PTR [ECX] + VMTOFFSET TObject.Destroy POP EAX CALL _ClassDestroy @@skip: { reraise the exception } CALL _RaiseAgain {$ENDIF} end; class function TObject.NewInstance: TObject; begin Result := InitInstance(_GetMem(InstanceSize)); end; class function TObject.InitInstance(Instance: Pointer): TObject; asm PUSH EBX PUSH ESI PUSH EDI MOV EBX,EAX MOV EDI,EDX STOSD MOV ECX,[EBX].vmtInstanceSize XOR EAX,EAX PUSH ECX SHR ECX,2 DEC ECX REP STOSD POP ECX AND ECX,3 REP STOSB MOV EAX,EDX MOV EDX,ESP @@0: MOV ECX,[EBX].vmtIntfTable TEST ECX,ECX JE @@1 PUSH ECX @@1: MOV EBX,[EBX].vmtParent TEST EBX,EBX JE @@2 MOV EBX,[EBX] JMP @@0 @@2: CMP ESP,EDX JE @@5 @@3: POP EBX MOV ECX,[EBX].TInterfaceTable.EntryCount ADD EBX,4 @@4: MOV ESI,[EBX].TInterfaceEntry.VTable TEST ESI,ESI JE @@4a MOV EDI,[EBX].TInterfaceEntry.IOffset MOV [EAX+EDI],ESI @@4a: ADD EBX,TYPE TInterfaceEntry DEC ECX JNE @@4 CMP ESP,EDX JNE @@3 @@5: POP EDI POP ESI POP EBX end; Почти весь. Это код создания любого (почти) объекта Delphi. Этот код автоматически подключается компилятором в месте создания объекта. Вот скажи: где больше процесс конструирования лежит на программисте, в Delphi, где все делает компилятор и код один для любого объекта, или в С++, где конструкторы пишет программист? |
|
Сообщ.
#3084
,
|
|
|
|
Цитата Romkin @ KILLER, во второй цитате речь идет про унаследованную функциональность. А мы о ней, сейчас как раз и беседуем Цитата Romkin @ Ну-ну. Вот тебе код конструктора: Цитата Romkin @ Почти весь. Это код создания любого (почти) объекта Delphi. Этот код автоматически подключается компилятором в месте создания объекта. Вот скажи: где больше процесс конструирования лежит на программисте, в Delphi, где все делает компилятор и код один для любого объекта, или в С++, где конструкторы пишет программист? Эээ А где в С++ конструкторы пишет программист? Или ты что имел ввиду? Вы типо не пишите конструкторы? В С++ я пишу конструктор, который всегда будет идентичен названию класса, только тогда, когда мне нужно инициализировать данные, которые расположены в классе, если я не напишу конструктор явно, его сгенерит компилятор автоматически, деструктор - автоматически удалит объект, мне не нужно писать ничего, единственно, если я пишу враппер над каким то указателем, без использования STL/boost, то тогда память которую я выделил ручками, я ручками и буду освобождать в деструкторе, все.А вто насчет конструкторов в С++ которые ручками пишет программист, и которые ручками не пишет программист на Делфи, ты покажи, а то я не въехал, о чем разговор, вроде ассемблерный код, который создает объект я не пишу |
|
Сообщ.
#3085
,
|
|
|
|
Цитата Romkin @ Брр. Тебе уже объясняли, что в Delphi объект единая сущность, он не делится на предков/потомков и тому подобное. Поэтому деструктор тоже один. Конструктор - тоже. В отличие от С++, в котором объект это целая шведская семья ![]() Правильно ли я понимаю, что создав TButton (в Delphi), я не смогу передать созданный экземпляр в метод, который принимает на вход TAbstractButton? Ведь TButton - неделимая сущность... |
|
Сообщ.
#3086
,
|
|
|
|
Цитата DesweR @ Цитата Повстанець @ Ссылочные типы ввели из-за того, что по другому не возможно реализовать сборщик мусора. Объектные типы оставили, чтобы разгрузить сборщик мусора и добавить быстродействие. В делфи, как всегда, фичу ввели, но наполовину. Ссылочные типы есть. Сборщика мусора нет. Начнём с того, что в основе методологии ООП лежит понятие "объект", целями "объекта" являются отражение абстрактной модели некой проблемы и наличие средств её решения, что вытекает в такие свойства "объекта", как "состояние" и "поведение" и как правило они напрямую взаимосвязанные, а наличие нескольких однотипных "объектов", со своими индивидуальными "состояниями", определяет ещё одно свойство - "уникальность", получается, что каждый отдельно взятый "объект", несмотря на наличие одного и того же интерфейса "средств решения проблемы" из общего числа однотипных ему "объектов", нацелен на решение конкретной проблемы, т.е. "объекты" могут использоваться совершенно разными способами и иметь своё индивидуальное "состояние" и соответственно "поведение" и так как "объекты" сами по себе, отдельно взятые, находятся в состоянии покоя, для их функционирования и получения результата необходимо внешнее воздействие других "объектов", это осуществляется путём передачи "объектов" через цепочку других "объектов" - субъектов, воздействующие на "состояние" "объектов", очень важный момент - это сохранение и передача изменённого "состояния" "объекта" на протяжении всех этапов цепочки, с возможным возвратом изменённого в итоге "состоянием", в конкретно взятом ОО ЯП это достигается путём передачи "объекта" не по "значению" а по указателю на место хранения "значения" "объекта" (переменной-ссылки), такой важный момент по определению ООП обязан быть прозрачным, это приоритетнее прозрачности копирования (и хранения) по значению, иначе, как заметил Romkin, это больше походит на структурное программирование. Это было "Раз". Второе: "динамичность объектов", тут разжёвывать не надо - это динамическое управление существованием некоторого множества "объектов", взаимодействующих друг с другом, статичными объектами этого не добится. Третье, неразрывно связано со вторым: "полиморфизм" Цитата Положение теории типов, согласно которому имена (например, переменных) могут обозначать объекты разных (но имеющих общего родителя) классов. Следовательно, любой объект, обозначаемый полиморфным именем, может по своему реагировать на некий общий набор операций. Причем тут это все? Ссылочная семантика объяснима(и мне даже больше нравится, как я уже писал), речь о том, что внутри языка существует абсолютно нелогичное разделение на типы-значения и типы-ссылки. Цитата Так возможностей не прибавляется. Просто непродуманный дизайн создания объектов.А кто там говорил про "большие возможности - большая ответственность" а? Цитата Чтобы понять, нужно вызывать или нет, придется лезть в код...Цитата KILLER @ Та ладно Вернемся к виртуальным конструкторам? Что будет если вызвался конструктор производного класса раньше чем конструктор базового инициализировал свой член, который конструктор производного, так тщетно пытается заюзать? ССЗБ будет, не нет необходимости - не вызывай. Ладно, обсуждали все это. Понятие инварианта класса для некоторых видимо пустой звук Цитата правила не отличаются, точнее их всего два: значимый тип и ссылочный тип (а отсутствие одного из них - не представляется возможным). "Правила не отличаются" и "их два" противоречит друг другу. Проблема не в том, чтобы зазубрить и помнить, а в том, что в таком разделении в рамках одного языка нет никакой необходимости. Цитата Во вторых: тогда уж "кривая система типов" в языке - это не "куда не плюнь - свои правила", а ограниченный ассортимент встроенных типов, влекущих за собой "собираем из того, что есть" и "осторожно! торчат гвозди" (здесь я про C++ и тип std::string в частности). Приводи пример с С++. Цитата Я рад, что есть прогресс и ты берешься за умные книжки, которые тут советывали А если по tapl, то система типов - это гибко управляемый синтаксический метод доказательства отсутствия определённых видов поведения при помощи классификации выражений языка по разновидностям вычисляемых или значений У С/С++ есть только одна "проблема" в системе типов - низкоуровневые указатели. Правда все плохое, что о них говорят в плане системы типов не является корректными примерами с точки зрения стандарта языка. Цитата вот декларирование переменной std::string включает в себя нюансы "определённых видов поведения"? Подробнее. Цитата Еще раз, С++ не чисто прикладной язык. На уровне стандарта сделать так - означало бы отказаться от многих возможных применений языка.Цитата D_KEY @ Согласен. В чистом С++ это есть на уровне шаблонов и только на время компиляции. В рантайм это не вынести, поскольку противоречит принципу "что не использую, за то не плачу". ... Согласен. Но не допустимо на уровне чистого С++, ибо также противоречит вышеуказанному принципу и ограничивает сферы применения языка. Вот на почве такого "жлобства" (в случаях когда оно не оправданно) у программистов С++ определённо выработалось "статическое мышление", а как же работа с динамическими объектами? А ведь это же одна из тех вещей, ради которой и создавалось ООП и не использование которой, так яростно критикуется противниками этой парадигмы. Может быть решено на уровне библиотеки. Цитата Вот уж реализации шаблонов и макросов на уровне среды разработки - точно не приводят к потерям в конечном результате. Приводят. Почему в данном случае должна страдать переносимость, если ничего "плохого" в рантайме не будет - эти средства используются во время компиляции ?Хотя на счет макросов еще могу согласится, но не на счет шаблонов. Добавлено Цитата Romkin @ Тебе уже объясняли, что в Delphi объект единая сущность, он не делится на предков/потомков и тому подобное. Поэтому деструктор тоже один. Конструктор - тоже. В отличие от С++, в котором объект это целая шведская семья ![]() А теперь, пожалуйста, тоже самое, только с дополнительными пояснениями по инвариантам класса. Объект единое целое, никто не спорит, но объект производного класса так же является и объектом базового, а гарантировать это в состоянии только конструктор базового класса. Добавлено Romkin, ну так что на счет задачки по интерфейсам? |
|
Сообщ.
#3087
,
|
|
|
|
Цитата KILLER @ Как раз таки, вот такие случаи - очень часто ведут к ошибкам, причем не компиляции, тут не нужно ослепнуть, тут всеголишь нужно забыть, что ты за каким то фигом завел в базовом классе член, который используется производным(что в принципе и правильно), но работашь ты с этим объектом в производном классе, до того как его поринициализировал базовый С таким же успехом ты можешь начать использовать экземпляр класса до его создания (забыл, перепутал местами). Цитата Flex Ferrum @ Правильно ли я понимаю, что создав TButton (в Delphi), я не смогу передать созданный экземпляр в метод, который принимает на вход TAbstractButton? Ведь TButton - неделимая сущность... Нет конечно и думаю ты понимаешь почему Цитата D_KEY @ Причем тут это все? Ссылочная семантика объяснима(и мне даже больше нравится, как я уже писал), речь о том, что внутри языка существует абсолютно нелогичное разделение на типы-значения и типы-ссылки. Устал уже, докажи в чём именно не логичность и как ты это представляешь в идеале (в ОО ЯП)? Цитата D_KEY @ Так возможностей не прибавляется. Просто непродуманный дизайн создания объектов. Не непродуманный, а тонко настраиваемый, уже обсуждали по пятому кругу. Цитата D_KEY @ Понятие инварианта класса для некоторых видимо пустой звук Уж кто бы говорил У кого там негласное "табу" в языке на вызов чего-либо из конструктора?Цитата D_KEY @ Я рад, что есть прогресс и ты берешься за умные книжки, которые тут советывали Ну всё, я сейчас покраснею D_KEY ей богу задрал уже со своим нано-троллингом. А TAPL, в этой ветке обсуждения, я вам уже раз десять советовал почитать. Цитата D_KEY @ У С/С++ есть только одна "проблема" в системе типов - низкоуровневые указатели. Правда все плохое, что о них говорят в плане системы типов не является корректными примерами с точки зрения стандарта языка. Но зато с точки зрения прагматики - это плохо. Цитата D_KEY @ "Правила не отличаются" и "их два" противоречит друг другу. И в чём тут противоречие? В месте хранения значения? P.S. Извиняюсь за тавтологию, указатель на "значение", хранится по значению в переменной-ссылке. Цитата D_KEY @ Приводи пример с С++. Думаю вам и так известен std::string, владеющий "строкой" Цитата D_KEY @ Еще раз, С++ не чисто прикладной язык. На уровне стандарта сделать так - означало бы отказаться от многих возможных применений языка. Ну тогда на кой ляд вы навязываете свои правила языка всем и вся? Цитата D_KEY @ если ничего "плохого" в рантайме не будет - эти средства используются во время компиляции? Это уже вопрос к нам? Цитата D_KEY @ Объект единое целое, никто не спорит, но объект производного класса так же является и объектом базового, а гарантировать это в состоянии только конструктор базового класса. В Delphi это гарантирует просто конструктор класса, см. пост Ромкина. |
|
Сообщ.
#3088
,
|
|
|
|
Цитата DesweR @ Думаю вам и так известен std::string, владеющий "строкой" И что в этом плохого? Что плохого в Rope и CoW-сценариях реализации string мы уже обсудили. В многопоточном окружении все бенифиты от таких подходов сходят "на нет". Цитата DesweR @ Нет конечно и думаю ты понимаешь почему ![]() Так, теперь представим себе, и экземпляр базового класса, и экземпляр потомка могут существовать (я имею в виду разные экземпляры), т. е. что базовый класс не является абстрактным. И базовый класс имеет конструктор, который позволяет сделать дубликат из уже имеющегося другого его экземпляра (конструктор копий). Мы только что выяснили, что потомок может использоваться в методах, умеющих работать только с его родителем (базовым классом). Следовательно, копирующий конструктор имеет полное право (и совершенно логичное!) принять на вход любого потомка базового класса и сделать дубликат... только той его части, которая является базовой. Это то, что в C++ называется "срезкой". Заметь, такого рода поведение вполне логично, допустимо, вписывается в ОО-модель, и легко может существовать в языках с ссылочной семантикой объектов. |
|
Сообщ.
#3089
,
|
|
|
|
Цитата DesweR @ С таким же успехом ты можешь начать использовать экземпляр класса до его создания (забыл, перепутал местами). Вот именно что не могу, мне ведь выдаст ошибку на стадии компиляции А вот юзнуть в конструкторе член базового класса, который еще не инициализирован вполне реально, и даже более того, это очень сильно реально, потому как используя член, тебе нужно знать где он объявлен, в базовом классе или в производном, иначе ты точно перепутаешь и юзнешь его не там где нужно Цитата DesweR @ Нет конечно и думаю ты понимаешь почему Я не понимаю, позавчера вы говорили, что потомок у вас отделяется от предка - как два пальца обосвальт, и вообще потомок - это отдельная сущность, предок - отдельная, а сегодня вы уже говорите, что у вас это все один неделимый объект, который имеет один конструктор и деструктор , отсюда напрашивается вопрос, эээ, а как это так? Получается у вас нет и виртуальных деструкторов, которые вы там пиарили когда то? Нет ведь, конструктор один и деструктор один - на всю иерархию классов, верно ведь?... И как это вообще работает? Я уже запутался, а еще даже в дебри не уходили, а только вокруг да около топчемся Цитата DesweR @ В Delphi это гарантирует просто конструктор класса, см. пост Ромкина. Один конструктор - на всю иерархию классов, верно ведь? |
|
Сообщ.
#3090
,
|
|
|
|
Цитата DesweR @ Цитата KILLER @ Как раз таки, вот такие случаи - очень часто ведут к ошибкам, причем не компиляции, тут не нужно ослепнуть, тут всеголишь нужно забыть, что ты за каким то фигом завел в базовом классе член, который используется производным(что в принципе и правильно), но работашь ты с этим объектом в производном классе, до того как его поринициализировал базовый С таким же успехом ты можешь начать использовать экземпляр класса до его создания (забыл, перепутал местами). До создания нет экземпляра Так кого использовать и как? Цитата Цитата D_KEY @ Причем тут это все? Ссылочная семантика объяснима(и мне даже больше нравится, как я уже писал), речь о том, что внутри языка существует абсолютно нелогичное разделение на типы-значения и типы-ссылки. Устал уже, докажи в чём именно не логичность и как ты это представляешь в идеале (в ОО ЯП)? Везде ссылочная семантика. Проблему производительности работы с примитивными типами решается за счет объявления их иммутабельными и запрета наследования от них. В этом случае оптимизатор сможет заменить ссылки на такие объекты на непосредственные значения, поскольку это не повлияет на видимое поведение. Цитата Обсуждали Цитата D_KEY @ Так возможностей не прибавляется. Просто непродуманный дизайн создания объектов. Не непродуманный, а тонко настраиваемый, уже обсуждали по пятому кругу. Непродуманный Цитата Именно потому, что конструктор порождает объект, а вызов полиморфных методов без соблюдения инварианта я логичным не назову, не говоря уже о том, что объекта еще нет, поэтому и о полиморфизме речи не идет.Цитата D_KEY @ Понятие инварианта класса для некоторых видимо пустой звук Уж кто бы говорил У кого там негласное "табу" в языке на вызов чего-либо из конструктора?Цитата Вообще-то это я его тебе советовал. Или korvin. Точно не помню.Цитата D_KEY @ Я рад, что есть прогресс и ты берешься за умные книжки, которые тут советывали Ну всё, я сейчас покраснею D_KEY ей богу задрал уже со своим нано-троллингом. А TAPL, в этой ветке обсуждения, я вам уже раз десять советовал почитать. Может и Мейера ты читать советовал? Цитата Он и есть "строка". Его реализация не важна.Цитата D_KEY @ Приводи пример с С++. Думаю вам и так известен std::string, владеющий "строкой" Цитата Кто навязывает?Цитата D_KEY @ Еще раз, С++ не чисто прикладной язык. На уровне стандарта сделать так - означало бы отказаться от многих возможных применений языка. Ну тогда на кой ляд вы навязываете свои правила языка всем и вся? Я же сказал, что классы как полноценные объекты - это очень хорошо. Просто пояснил, почему в С++ это не так. Цитата Это не может гарантировать конструктор класса. Цитата D_KEY @ Объект единое целое, никто не спорит, но объект производного класса так же является и объектом базового, а гарантировать это в состоянии только конструктор базового класса. В Delphi это гарантирует просто конструктор класса, см. пост Ромкина. |