Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.192] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 411 412 [413] 414 415 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#6181
,
|
|
|
|
Цитата Мяут-Настоящий @ A и B - очень похожие сущности, но тогда им бог велел от общего класса наследоваться Откуда такой вывод? Будь они похожи у них конечно же был бы общий предок, который мы могли использовать в качестве C. Добавлено Цитата MyNameIsIgor @ Цитата korvin @ Эм... каких требований не хватает? Определение C = A or B вроде вполне однозначно. Впрочем если есть какие-то конкретные вопросы -- задавай. Ну, например, если имеем ![]() ![]() foo(a : A) и мы сделали ![]() ![]() var x : C x = new B то как должен вести себя ![]() ![]() foo(x) ? Ошибка компиляции. Либо нужно писать что-то вроде ![]() ![]() if (x instanceof A) { foo((A) x); } Добавлено Цитата MyNameIsIgor @ Кто бы спорил... Тут, imho, всё зависит от требований, в том числе желаемого синтаксиса. Кроме неуниверсальности у данного решения есть еще проблема: как бы это сказать, разброс определения. Т.е. мы раскидываем определение типа C по типам A и B. Если у нас много типов, то такие зависимости может быть сложно отследить. Для ![]() ![]() type A type B type C type D type W = A or B type X = C or D type Y = B or C or D type Z = A or Y получим ![]() ![]() class Z; class Y : Z; class X; class W; class A : W, Z; class B : W, Y; class C : X, Y; class D : X, Y; И они хуже отражают суть + у A, B, C и D могут быть и другие предки, не связанные с W, X, Y, Z. |
|
Сообщ.
#6182
,
|
|
|
|
Цитата korvin @ Ошибка компиляции. Либо нужно писать что-то вроде ![]() ![]() if (x instanceof A) { foo((A) x); } Ну, если прямо C засовывать в foo, то да, ошибка компиляции. Аналогом instanceof будет boost::get - например. |
|
Сообщ.
#6183
,
|
|
|
|
Цитата korvin @ Ошибка компиляции. А если динамичеки присваивать? ![]() ![]() var x : C x = new B foo(x) x = new A foo(x) ? Добавлено Если хочется строгой типизации (правда в одну сторону), то можно реализовать на перегрузках оператора присваивания (на С++ тут лучше получится). ![]() ![]() TCommon<T1, T2 .. Tn> = record strict private F1: T1; F2: T2; public class operator Implicit(A1: T1): TCommon<T1, T2>; class operator Implicit(A1: TCommon<T1, T2>): T1; class operator Implicit(A2: T2): TCommon<T1, T2>; class operator Implicit(A2: TCommon<T1, T2>): T2; ... end; var C: TCommon<TA, TB>; begin C := TA.Create; C := TB.Create; C := TG.Create; //ошибка Ну а если не хочется, то в рантайме без проблем (ну а тут у нас). |
|
Сообщ.
#6184
,
|
|
|
|
Цитата DesweR @ Ну а если не хочется, то в рантайме без проблем (ну а тут у нас). А мой пример имеет какие-то проблемы в рантайме? |
|
Сообщ.
#6185
,
|
|
|
|
Цитата MyNameIsIgor @ А мой пример имеет какие-то проблемы в рантайме? Да нет наверное, хотя я его не видел Добавлено Там можно задать ограничение множеством? |
|
Сообщ.
#6186
,
|
|
|
|
Цитата DesweR @ А если динамичеки присваивать? ![]() ![]() var x : C x = new B foo(x) x = new A foo(x) ? Нет, ты не понял, у нас сигнатура foo ![]() ![]() foo (x : A) из ![]() ![]() var x : A следует, что x : C, т.е. его можно спокойно передать в любое место, где требуется C. Но из ![]() ![]() var x : C не следует, что x : A всегда, он может быть как A, так и B. Соответственно его нельзя свободно без проверки передать туда, где требуется A. |
|
Сообщ.
#6187
,
|
|
|
|
Цитата korvin @ Нет, ты не понял, у нас сигнатура foo (x : A), из x : A следует, что x : C, но из x : C не следует, что x : A всегда, нужна проверка и каст. У нас же статическая типизация. Но нам x: C может приходить извне, вообще из другого модуля. И при раздельной компиляции мы можем просто не иметь возможности вывести, что же туда запихнули. Опять же какая-то фабрика может производить x: C, которые хз что. Чтобы статически выводить это всё, надо очень сильно усложнять модель компиляции. |
|
Сообщ.
#6188
,
|
|
|
|
Цитата MyNameIsIgor @ надо очень сильно усложнять модель компиляции. Или очень сильно упростить - валить все в одну кучу и никаких библиотек! |
|
Сообщ.
#6189
,
|
|
|
|
Цитата D_KEY @ Или очень сильно упростить - валить все в одну кучу и никаких библиотек! Мне кажется, что это как раз усложнение |
|
Сообщ.
#6190
,
|
|
|
|
Что-то я не пойму сути дискуссии. Мы тут выдумываем новую форму полиморфизма?
По-любому у A и B должны быть общие черты, иначе foo(), окромя как банальным aka switch, не сможет с ними работать, тогда уж проще её перегрузить. В потивносм случае - на выбор class A: C или template <typename T> class C: T. |
|
Сообщ.
#6191
,
|
|
|
|
Цитата Qraizer @ По-любому у A и B должны быть общие черты, иначе foo(), окромя как банальным aka switch, не сможет с ними работать Ну так вообще-то о том и речь. По сути, типы-суммы(то, что просит korvin) являются частным случаем алгебраических типов данных(упрощенно говоря - вариантных типов). А тут без сопоставления с образцом(aka switch) особо не разгуляешься. |
|
Сообщ.
#6192
,
|
|
|
|
А как вы относитесь к э-э-э... способу указания возвращаемого значения функции: переменная Result как в Delphi или инструкция return, как в остальных обсуждаемых языках? Какой способ по-вашему лучше и почему?
|
|
Сообщ.
#6193
,
|
|
|
|
А как в делфи происходит досрочный выход из функции?
|
|
Сообщ.
#6194
,
|
|
|
|
Цитата Повстанець @ А как в делфи происходит досрочный выход из функции? ![]() ![]() Exit; |
|
Сообщ.
#6195
,
|
|
|
|
Цитата korvin @ В VB вроде так же. Или почти также - имя функции в качестве хранилища ее результата. переменная Result как в Delphi |